Je viens d'avoir VS2012 et j'essaie de me débrouiller avec async
.
Disons que j'ai une méthode qui récupère une valeur à partir d'une source bloquante. Je ne veux pas que l'appelant de la méthode soit bloqué. Je pourrais écrire la méthode pour qu'elle prenne un callback qui est invoqué lorsque la valeur arrive, mais comme j'utilise C# 5, je décide de rendre la méthode asynchrone pour que les appelants n'aient pas à s'occuper des callbacks :
// contrived example (edited in response to Servy's comment)
public static Task<string> PromptForStringAsync(string prompt)
{
return Task.Factory.StartNew(() => {
Console.Write(prompt);
return Console.ReadLine();
});
}
Voici un exemple de méthode qui l'appelle. Si PromptForStringAsync
n'était pas asynchrone, cette méthode nécessiterait d'imbriquer un callback dans un callback. Avec l'asynchronie, je peux écrire ma méthode de manière très naturelle :
public static async Task GetNameAsync()
{
string firstname = await PromptForStringAsync("Enter your first name: ");
Console.WriteLine("Welcome {0}.", firstname);
string lastname = await PromptForStringAsync("Enter your last name: ");
Console.WriteLine("Name saved as '{0} {1}'.", firstname, lastname);
}
Jusqu'à présent, tout va bien. Le problème est que lorsque je appelez GetNameAsync :
public static void DoStuff()
{
GetNameAsync();
MainWorkOfApplicationIDontWantBlocked();
}
Le but de GetNameAsync
est que c'est asynchrone. Je n'ai pas quiere de la bloquer, car je veux retourner au MainWorkOfApplicationIDontWantBlocked dès que possible et laisser GetNameAsync faire son travail en arrière-plan. Cependant, l'appeler de cette façon me donne un avertissement du compilateur sur le fichier GetNameAsync
ligne :
Warning 1 Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
Je suis parfaitement conscient que "l'exécution de la méthode en cours continue avant que l'appel ne soit terminé". C'est le point de code asynchrone, non ?
Je préfère que mon code soit compilé sans avertissement, mais il n'y a rien à "réparer" ici, car le code fait exactement ce que je veux qu'il fasse. Je peux me débarrasser de l'avertissement en stockant la valeur de retour de GetNameAsync
:
public static void DoStuff()
{
var result = GetNameAsync(); // supress warning
MainWorkOfApplicationIDontWantBlocked();
}
Mais maintenant j'ai du code superflu. Visual Studio semble comprendre que j'ai été contraint d'écrire ce code inutile, car il supprime l'avertissement normal "valeur jamais utilisée".
Je peux aussi me débarrasser de l'avertissement en enveloppant GetNameAsync dans une méthode qui n'est pas asynchrone :
public static Task GetNameWrapper()
{
return GetNameAsync();
}
Mais c'est même plus code superflu. Je dois donc écrire du code dont je n'ai pas besoin ou tolérer un avertissement inutile.
Mon utilisation de l'asynchronisme est-elle incorrecte ?