204 votes

Utiliser "async" dans une application console en C#

J'ai ce code simple :

public static async Task<int> SumTwoOperationsAsync()
{
    var firstTask = GetOperationOneAsync();
    var secondTask = GetOperationTwoAsync();
    return await firstTask + await secondTask;
}

private async Task<int> GetOperationOneAsync()
{
    await Task.Delay(500); // Just to simulate an operation taking time
    return 10;
}

private async Task<int> GetOperationTwoAsync()
{
    await Task.Delay(100); // Just to simulate an operation taking time
    return 5;
}

Super. Ça se compile.

Mais disons que j'ai une application console et que je veux exécuter le code ci-dessus (en appelant SumTwoOperationsAsync() ).

static void Main(string[] args)
{
     SumTwoOperationsAsync();
}

Mais j'ai lu que (en utilisant sync ) Je dois synchroniser tout le chemin en haut y en bas :

Cela signifie-t-il que mon Main doit être marquée comme async ?

Eh bien, il ne peut pas être parce qu'il y a une erreur de compilation :

un point d'entrée ne peut pas être marqué avec le modificateur 'async'.

Si je comprends bien l'aspect asynchrone, le fil d'exécution entrera dans le Main fonction SumTwoOperationsAsync appellera les deux fonctions et sortira. Mais jusqu'à ce que le SumTwoOperationsAsync

Qu'est-ce que je rate ?

348voto

Stephen Cleary Points 91731

Dans la plupart des types de projets, votre async "haut" et "bas" se termineront par un async void ou renvoyer un Task à votre cadre.

Toutefois, les applications de la console ne le permettent pas.

Vous pouvez soit faire un Wait sur la tâche retournée :

static void Main()
{
  MainAsync().Wait();
  // or, if you want to avoid exceptions being wrapped into AggregateException:
  //  MainAsync().GetAwaiter().GetResult();
}

static async Task MainAsync()
{
  ...
}

ou vous pouvez utiliser votre propre contexte comme celui que j'ai écrit :

static void Main()
{
  AsyncContext.Run(() => MainAsync());
}

static async Task MainAsync()
{
  ...
}

Plus d'informations pour async Les applications de la console sont sur mon blog .

101voto

Voici la façon la plus simple de procéder

static void Main(string[] args)
{
    Task t = MainAsync(args);
    t.Wait();
}

static async Task MainAsync(string[] args)
{
    await ...
}

4voto

user2987314 Points 11

Comme une solution rapide et très étendue :

Résultat de la tâche

Task.Result et Task.Wait ne permettent pas d'améliorer l'extensibilité lorsqu'ils sont utilisés avec des E/S, car ils font en sorte que le thread appelant reste bloqué en attendant la fin des E/S.

Lorsque vous appelez .Result sur une tâche incomplète, le thread qui exécute la méthode doit attendre la fin de la tâche, ce qui l'empêche d'effectuer toute autre tâche utile dans l'intervalle. Cela annule l'avantage de la nature asynchrone de la tâche.

notasync

1voto

Richard Keene Points 308

Ma solution. Le JSONServer est une classe que j'ai écrite pour exécuter un serveur HttpListener dans une fenêtre console.

class Program
{
    public static JSONServer srv = null;

    static void Main(string[] args)
    {
        Console.WriteLine("NLPS Core Server");

        srv = new JSONServer(100);
        srv.Start();

        InputLoopProcessor();

        while(srv.IsRunning)
        {
            Thread.Sleep(250);
        }

    }

    private static async Task InputLoopProcessor()
    {
        string line = "";

        Console.WriteLine("Core NLPS Server: Started on port 8080. " + DateTime.Now);

        while(line != "quit")
        {
            Console.Write(": ");
            line = Console.ReadLine().ToLower();
            Console.WriteLine(line);

            if(line == "?" || line == "help")
            {
                Console.WriteLine("Core NLPS Server Help");
                Console.WriteLine("    ? or help: Show this help.");
                Console.WriteLine("    quit: Stop the server.");
            }
        }
        srv.Stop();
        Console.WriteLine("Core Processor done at " + DateTime.Now);

    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X