567 votes

Async sur la méthode principale de l’application console

Je suis assez novice dans le monde async, et j’essaie de comprendre comment m’assurer que ma méthode principale d’une application de console va effectivement async

Je sais que cela ne fonctionne pas async « du haut ». mais puisque vous ne pouvez pas marquer la Main avec async je n’ai aucune idée de comment m’assurer que. Toutes les idées ? Merci !

537voto

Stephen Cleary Points 91731

Comme vous l'avez découvert, dans VS11 le compilateur refusera un async Main méthode. Cela était autorisé (mais jamais recommandé) dans VS2010 avec la Async CTP.

J'ai récents messages de blog sur async/await et asynchrone programmes de la console en particulier. Voici quelques informations de fond dès l'intro post:

Si "attendent" voit que le awaitable n'est pas terminé, alors il s'agit de manière asynchrone. Il raconte l'awaitable pour exécuter le reste de la méthode lorsqu'elle est terminée, et puis retourne à partir de la méthode asynchrone. Attendent permettra aussi de saisir l'actuel contexte quand il passe le reste de la méthode à la awaitable.

Plus tard, quand le awaitable se termine, il va exécuter le reste de la méthode asynchrone (dans la capture d'contexte).

Voici pourquoi c'est un problème dans les programmes de la Console avec un async Main:

Le souvenir de notre intro post qu'une méthode asynchrone sera de retour à son visiteur avant qu'il soit terminé. Cela fonctionne parfaitement dans l'INTERFACE utilisateur des applications (la méthode renvoie simplement à l'INTERFACE de boucle d'événement) et ASP.NET les applications (le retour de la méthode du fil, mais conserve la demande de son vivant). Il ne fonctionne pas si bien pour les programmes de la Console: Principal revient à l'OS - de sorte que votre programme se termine.

Une solution est de fournir à votre propre contexte d'une "boucle principale" pour votre programme de console async-compatible.

Si vous avez une machine avec Async CTP, vous pouvez utiliser GeneralThreadAffineContext de Mes Documents\Visual Studio Async CTP\Samples(C# Tests) Tests Unitaires\AsyncTestUtilities. Alternativement, vous pouvez utiliser AsyncContext de mon Nito.AsyncEx package NuGet.

Voici un exemple d'utilisation AsyncContext; GeneralThreadAffineContext a presque identique utilisation:

using Nito.AsyncEx;
class Program
{
    static void Main(string[] args)
    {
        AsyncContext.Run(() => MainAsync(args));
    }

    static async void MainAsync(string[] args)
    {
        Bootstrapper bs = new Bootstrapper();
        var list = await bs.GetList();
    }
}

393voto

Chris Moschini Points 7278

Vous pouvez résoudre ce problème avec ce concept simple :

Cela mettra tout vous sortir sur le pool de threads où vous souhaiteriez il (donc autres tâches vous démarrer/attendent ne tentez pas de rejoindre un Thread ils ne devraient pas), et attendre jusqu'à ce que tout est fait avant de fermer l’application Console. Aucun besoin pour les boucles spéciales ou à l’extérieur libs.

92voto

SnOrfus Points 6457

Vous pouvez le faire sans avoir besoin des bibliothèques externes également en procédant comme suit :

82voto

Cory Nelson Points 10540

Je vais ajouter un élément important que toutes les autres réponses ont négligé : annulation.

Une des grandes choses dans TPL est support d’annulation, et console apps ont une méthode d’annulation construite en (CTRL + C). C’est très simple pour les lier ensemble. Voilà comment j’ai tous mes apps de console async structurer :

19voto

Johan Falk Points 3073

N’ont pas besoin de cela beaucoup encore, mais quand j’ai utilisé l’application console pour les tests rapides et async requis je l’ai ai juste résolu comme ceci :

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