377 votes

Devez-vous mettre à la Tâche.Exécuter dans une méthode pour le rendre asynchrone?

J'essaie de comprendre async vous attendent dans la forme la plus simple. Je veux créer une méthode très simple qui ajoute deux nombres pour les besoins de cet exemple, accordé, il n'est pas temps de traitement à tous, c'est juste une question de formulation d'un exemple ici.

Exemple 1:

private async Task DoWork1Async()
{
    int result = 1 + 2;
}

Exemple 2:

private async Task DoWork2Async()
{
    Task.Run( () =>
    {
        int result = 1 + 2;
    });
}

Si j'attends DoWork1Async() le code est exécuté de manière synchrone ou asynchrone?

Ai-je besoin pour envelopper la synchronisation du code de la Tâche.Exécuter pour rendre la méthode awaitable ET asynchrone afin de ne pas bloquer le thread d'INTERFACE utilisateur?

Je suis en train de voir si ma méthode est une Tâche ou retourne Tâche dois-je placer le code de la Tâche.Courir pour le rendre asynchrone.

Question stupide, mais je suis sûr que je voir des exemples sur le net où les gens sont en attente de code qui n'a rien asynchrone à l'intérieur et n'est pas enroulé dans une Tâche.Exécuter ou StartNew.

708voto

Stephen Cleary Points 91731

Tout d'abord, nous allons clarifier la terminologie: "asynchrone" (async) signifie qu'il peut céder le contrôle de retour pour le thread appelant avant qu'il ne commence. Dans un async méthode, ces "rendement" points sont await expressions.

C'est très différent que le terme "asynchrone", comme (sig)utilisé par la documentation MSDN pour les années à dire "s'exécute sur un thread d'arrière-plan".

Pour de plus amples confondre la question, async est très différent de "awaitable"; il y a quelques async méthodes dont le type de retour ne sont pas awaitable, et de nombreuses méthodes de retour awaitable types qui ne sont pas async.

Assez sur ce qu'ils ne sont pas; voici ce qu'ils sont:

  • L' async mot-clé permet une méthode asynchrone (qui est, elle permet d' await expressions). async méthodes peuvent renvoyer Task, Task<T>, ou (si vous devez) void.
  • Tout type qui suit un certain modèle peut être awaitable. La plus courante awaitable types sont Task et Task<T>.

Donc, si nous reformuler votre question "comment puis-je exécuter une opération sur un thread d'arrière-plan d'une manière qui il est awaitable", la réponse est d'utiliser Task.Run:

private Task<int> DoWorkAsync() // No async because the method does not need await
{
  return Task.Run(() =>
  {
    return 1 + 2;
  });
}

(Mais ce modèle est une mauvaise approche, voir ci-dessous).

Mais si votre question est "comment puis-je créer un async méthode qui peut le rendement jusqu'à son appelant au lieu de le bloquer", la réponse est de déclarer la méthode async et l'utilisation await pour son "rendement" des points:

private async Task<int> GetWebPageHtmlSizeAsync()
{
  var client = new HttpClient();
  var html = await client.GetAsync("http://www.example.com/");
  return html.Length;
}

Ainsi, le motif de base des choses, c'est d'avoir async code dépendent de "awaitables" dans ses await expressions. Ces "awaitables" peut-être d'autres async méthodes ou tout simplement des méthodes régulières de retour awaitables. Régulièrement les méthodes retournant Task/Task<T> pouvez utiliser Task.Run d'exécuter du code sur un thread d'arrière-plan, ou (plus souvent) qu'ils peuvent utiliser TaskCompletionSource<T> ou l'un de ses raccourcis (TaskFactory.FromAsync, Task.FromResult, etc). Je ne pas recommander l'enchaînement d'un ensemble de méthode en Task.Run; les méthodes synchrones doivent avoir synchrone signatures, et il devrait être laissé au consommateur qu'il doit être enveloppé dans un Task.Run:

private int DoWork()
{
  return 1 + 2;
}

private void MoreSynchronousProcessing()
{
  // Execute it directly (synchronously), since we are also a synchronous method.
  var result = DoWork();
  ...
}

private async Task DoVariousThingsFromTheUIThreadAsync()
{
  // I have a bunch of async work to do, and I am executed on the UI thread.
  var result = await Task.Run(() => DoWork());
  ...
}

J'ai un async/await intro sur mon blog; à la fin, il est intéressant de suivi des ressources. La MSDN docs pour async sont exceptionnellement bonnes, aussi.

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