Ich habe gerade VS2012 bekommen und versucht, es in den Griff zu bekommen async.
Angenommen, ich habe eine Methode, die einen Wert von einer blockierenden Quelle abruft. Ich möchte nicht, dass der Aufrufer der Methode blockiert. Ich könnte die Methode schreiben, um einen Rückruf anzunehmen, der beim Eintreffen des Werts aufgerufen wird. Da ich jedoch C # 5 verwende, entscheide ich mich, die Methode asynchron zu machen, damit Anrufer sich nicht mit Rückrufen befassen müssen:
// 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();
});
}
Hier ist eine Beispielmethode, die es aufruft. Wenn dies PromptForStringAsyncnicht asynchron wäre, müsste für diese Methode ein Rückruf in einen Rückruf verschachtelt werden. Mit Async kann ich meine Methode auf ganz natürliche Weise schreiben:
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);
}
So weit, ist es gut. Das Problem ist , wenn ich anrufen GetNameAsync:
public static void DoStuff()
{
GetNameAsync();
MainWorkOfApplicationIDontWantBlocked();
}
Der springende Punkt GetNameAsyncist, dass es asynchron ist. Ich möchte nicht, dass es blockiert wird, da ich so schnell wie möglich zu MainWorkOfApplicationIDontWantBlocked zurückkehren und GetNameAsync im Hintergrund ausführen lassen möchte. Wenn ich es jedoch so nenne, erhalte ich eine Compiler-Warnung in der GetNameAsyncZeile:
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.
Mir ist völlig bewusst, dass "die Ausführung der aktuellen Methode fortgesetzt wird, bevor der Aufruf abgeschlossen ist". Das ist der Punkt des asynchronen Codes, richtig?
Ich bevorzuge es, meinen Code ohne Warnungen zu kompilieren, aber hier gibt es nichts zu "reparieren", da der Code genau das tut, was ich beabsichtige. Ich kann die Warnung entfernen, indem ich den Rückgabewert von GetNameAsync:
public static void DoStuff()
{
var result = GetNameAsync(); // supress warning
MainWorkOfApplicationIDontWantBlocked();
}
Aber jetzt habe ich überflüssigen Code. Visual Studio scheint zu verstehen, dass ich gezwungen war, diesen unnötigen Code zu schreiben, da er die normale Warnung "Wert nie verwendet" unterdrückt.
Ich kann die Warnung auch entfernen, indem ich GetNameAsync in eine Methode einbinde, die nicht asynchron ist:
public static Task GetNameWrapper()
{
return GetNameAsync();
}
Aber das ist noch mehr überflüssig Code. Ich muss also Code schreiben, den ich nicht brauche oder eine unnötige Warnung toleriere.
Gibt es etwas an meiner Verwendung von Async, das hier nicht stimmt?
GetNameAsyncden vollständigen Namen zur Verfügung zu stellen, die vom Benutzer (dh zur Verfügung gestellt wurde Task<Name>, und nicht nur eine Rückkehr Task? DoStuffKönnte dann speichern , diese Aufgabe, und entweder awaites nach dem anderen Verfahren oder sogar passiert die Aufgabe zu , dass andere Methode, damit es könnte awaitoder Waites irgendwo innerhalb seiner Implementierung.
asyncSchlüsselwort.
PromptForStringAsyncerledigen Sie mehr Arbeit als nötig. Geben Sie einfach das Ergebnis von zurückTask.Factory.StartNew. Es ist bereits eine Aufgabe, deren Wert die in die Konsole eingegebene Zeichenfolge ist. Es besteht keine Notwendigkeit, darauf zu warten und das Ergebnis zurückzugeben. Dies bringt keinen neuen Wert.