126 votes

Comment appeler une méthode asynchrone dans Main ?

public class test
{
    public async Task Go()
    {
        await PrintAnswerToLife();
        Console.WriteLine("done");
    }

    public async Task PrintAnswerToLife()
    {
        int answer = await GetAnswerToLife();
        Console.WriteLine(answer);
    }

    public async Task<int> GetAnswerToLife()
    {
        await Task.Delay(5000);
        int answer = 21 * 2;
        return answer;
    }
}

Si je veux appeler Go dans la méthode main(), comment puis-je le faire ? J'essaye les nouvelles fonctionnalités de C#, je sais que je peux accrocher la méthode asynchrone à un événement et en déclenchant cet événement, la méthode asynchrone peut être appelée.

Mais que faire si je veux l'appeler directement dans la méthode principale ? Comment puis-je le faire ?

J'ai fait quelque chose comme

class Program
{
    static void Main(string[] args)
    {
        test t = new test();
        t.Go().GetAwaiter().OnCompleted(() =>
        {
            Console.WriteLine("finished");
        });
        Console.ReadKey();
    }

}

Mais il semble que ce soit une impasse et que rien ne s'affiche à l'écran.

155voto

Tim S. Points 30377

Votre Main peut être simplifiée. Pour C# 7.1 et plus récent :

static async Task Main(string[] args)
{
    test t = new test();
    await t.Go();
    Console.WriteLine("finished");
    Console.ReadKey();
}

Pour les versions antérieures de C# :

static void Main(string[] args)
{
    test t = new test();
    t.Go().Wait();
    Console.WriteLine("finished");
    Console.ReadKey();
}

Cela fait partie de la beauté de la async mot-clé (et fonctionnalité connexe) : l'utilisation et la nature déroutante des rappels sont considérablement réduites ou éliminées.

30voto

arviman Points 1663

Au lieu d'attendre, vous feriez mieux d'utiliser new test().Go().GetAwaiter().GetResult() puisque cela évitera que les exceptions soient enveloppées dans des AggregateExceptions, de sorte que vous pouvez simplement entourer votre méthode Go() d'un bloc try catch(Exception ex) comme d'habitude.

29voto

DavidG Points 12762

Depuis la sortie de C# v7.1 async main sont désormais disponibles, ce qui évite d'avoir à recourir aux solutions de contournement décrites dans les réponses déjà publiées. Les signatures suivantes ont été ajoutées :

public static Task Main();
public static Task<int> Main();
public static Task Main(string[] args);
public static Task<int> Main(string[] args);

Cela vous permet d'écrire votre code comme ceci :

static async Task Main(string[] args)
{
    await DoSomethingAsync();
}

static async Task DoSomethingAsync()
{
    //...
}

16voto

maxspan Points 310
class Program
{
    static void Main(string[] args)
    {
       test t = new test();
       Task.Run(async () => await t.Go());
    }
}

14voto

msoliman Points 732

Tant que vous accédez à l'objet résultat à partir de la tâche retournée, il n'est pas nécessaire d'utiliser GetAwaiter du tout (Seulement dans le cas où vous accédez au résultat).

static async Task<String> sayHelloAsync(){

       await Task.Delay(1000);
       return "hello world";

}

static void main(string[] args){

      var data = sayHelloAsync();
      //implicitly waits for the result and makes synchronous call. 
      //no need for Console.ReadKey()
      Console.Write(data.Result);
      //synchronous call .. same as previous one
      Console.Write(sayHelloAsync().GetAwaiter().GetResult());

}

si vous souhaitez attendre la fin d'une tâche et effectuer un traitement supplémentaire :

sayHelloAsyn().GetAwaiter().OnCompleted(() => {
   Console.Write("done" );
});
Console.ReadLine();

Si vous souhaitez obtenir les résultats de sayHelloAsync et les traiter de manière plus approfondie :

sayHelloAsync().ContinueWith(prev => {
   //prev.Result should have "hello world"
   Console.Write("done do further processing here .. here is the result from sayHelloAsync" + prev.Result);
});
Console.ReadLine();

Une dernière façon simple d'attendre une fonction :

static void main(string[] args){
  sayHelloAsync().Wait();
  Console.Read();
}

static async Task sayHelloAsync(){          
  await Task.Delay(1000);
  Console.Write( "hello world");

}

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