Tout d'abord, clarifions un peu la terminologie: "asynchrone" ( async) signifie qu'il peut redonner le contrôle au thread appelant avant qu'il ne démarre. Dans une asyncméthode, ces points de "rendement" sont des awaitexpressions.
Ceci est très différent du terme "asynchrone", car (mis) utilisé par la documentation MSDN pendant des années pour signifier "s'exécute sur un thread d'arrière-plan".
Pour confondre encore la question, asyncest très différent de "attendable"; il existe des asyncméthodes dont les types de retour ne sont pas attendus, et de nombreuses méthodes qui renvoient des types attendus qui ne le sont pas async.
Assez de ce qu'ils ne sont pas ; voici ce qu'ils sont :
- Le
asyncmot-clé autorise une méthode asynchrone (c'est-à-dire qu'il autorise les awaitexpressions). asyncméthodes peuvent revenir Task, Task<T>ou (si vous devez) void.
- Tout type qui suit un certain modèle peut être attendu. Les types attendus les plus courants sont
Tasket Task<T>.
Donc, si nous reformulons votre question en "comment puis-je exécuter une opération sur un thread d'arrière-plan d'une manière qui soit attendue", 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 une asyncméthode qui peut renvoyer à son appelant au lieu de bloquer", la réponse est de déclarer la méthode asyncet de l'utiliser awaitpour ses points "donnant":
private async Task<int> GetWebPageHtmlSizeAsync()
{
var client = new HttpClient();
var html = await client.GetAsync("http://www.example.com/");
return html.Length;
}
Ainsi, le modèle de base des choses est de faire asyncdépendre le code des "attendables" dans ses awaitexpressions. Ces "attendables" peuvent être d'autres asyncméthodes ou simplement des méthodes régulières renvoyant des attentes. Méthodes régulières de retour Task/ Task<T> peuvent utiliser Task.Runpour exécuter du code sur un thread d'arrière - plan, ou (plus souvent) , ils peuvent utiliser TaskCompletionSource<T>ou l' un de ses raccourcis ( TaskFactory.FromAsync, Task.FromResult, etc.). Je ne recommande pas d' envelopper une méthode entière dans Task.Run; les méthodes synchrones doivent avoir des signatures synchrones, et il convient de laisser au consommateur le soin de les inclure 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 une async/ awaitintro sur mon blog; à la fin, il y a de bonnes ressources de suivi. Les documents MSDN pour asyncsont également exceptionnellement bons.