Wenn die Methode void zurück, ist die gleiche, die Aufgabe an?
Ich versuche die async CTP, die versión 4.5 erlaubt die Verwendung von asynchronen Methoden, ohne zu schreiben, der Begin/End-Methoden.
Meine erste Sonde ist für die Ausführung einer asynchronen Methode, die "void" zurückgeben. Ich sehe ein paar Beispiele und das folgende tun:
private void btnAsync01_Click(object sender, RoutedEventArgs e)
{
UpdateTxtLog("click button: " + System.DateTime.Now);
method01Async();
UpdateTxtLog("after ethod01Async: " + System.DateTime.Now);
}
private async void method01Async()
{
await TaskEx.Run(() =>
{
UpdateTxtLog("Enter method01Async: " + System.DateTime.Now);
Thread.Sleep(10000);
UpdateTxtLog("exit method01Async: " + System.DateTime.Now);
});
}
In meinem WPF-Projekt habe ich eine textBox, wo die Ergebnisse zu sehen, und eine Schaltfläche, führen Sie die async-Methode.
In der asynchronen Methode, die ich verwenden, erwarten, dass nötig ist, weil die Methode ist asynchron, und die TasEx.Führen Sie zum erstellen eines neuen thread, in dem Sie den code auszuführen.
Meine Zweifel in diesem Punkt. In ein paar Beispiele, die ich sehen, wie zum erstellen einer async-Methode, die void zurückgibt, verwenden Sie diese Weise, die Aufgabe.Laufen oder TaskEx.Laufen.
Wenn ich mich nicht Irre, Aufgabe.Führen Sie einen neuen thread erstellen, wo die Methode auszuführen. Dann warum verwenden eine asynchrone Methode, wenn mit der Aufgabe, das erstellen eines neuen thread habe ich bekommen, was ich will, nicht blockiert den main thread?
Auch, wenn Sie die async-Methode Zugriff auf gemeinsame variable, muss ich vorsichtig sein mit der Parallelität, richtig? Also ich weiß nicht, der Vorteil bei der Verwendung von async-Methoden, zumindest in diesem Fall.
In der Tat, ich benutze den gleichen code, ohne async und ohne zu erwarten und das Ergebnis ist das gleiche, das Hauptprogramm nicht blockiert, und alles funktioniert wie ich erwarte. Die Methode ist diese:
private void method01Async()
{
TaskEx.Run(() =>
{
UpdateTxtLog("Enter method01Async: " + System.DateTime.Now);
Thread.Sleep(10000);
UpdateTxtLog("Exit method01Async: " + System.DateTime.Now);
});
}
Meine Frage ist, ist dies die richtige Art und Weise zu verwenden, async, wenn die Methode "void" zurückgeben?
- BTW, Die Visual Studio 11 Beta ist jetzt raus, der enthält die Funktionen von dem Async CTP-Version, mit einigen Verbesserungen und bug-fixes.
- Und was ist der Vorteil von os mit async-Methode in diesem Fall, wenn in der Methode, die ich benutze eine Aufgabe, und die Aufgabe, verwenden Sie eine niew thread? Wenn ich direkt eine Aufgabe, ohne ein async-Methode, bekomme ich das Verhalten. Vielleicht async-Methoden haben mehr Sinn, wenn die Methode einen Wert zurückgeben und für void-Methoden, ist es besser, direkt eine Aufgabe?
- Ich empfehle, dass alle
async
Methoden zurückTask
oderTask<TResult>
es sei denn, Sie sind event-Handler und zurückvoid
. Dies ermöglicht Ihnen das schreiben Sie, wenn nötig, und Fehler-handling sauberer, auch wenn einasync void
- Methode löst eine Ausnahme in einer WPF-Kontext, es wird direkt an den UI-nachrichtenschleife, soasync void
Methoden sind nicht wirklich "fire-and-forget"). - Nutzen Sie auch
Task.Run
nur zum ausführen von code auf den thread-pool. Sie könnenTask.Delay
für eine asynchrone warten, statt Warteschlangen eine SperrungSleep
.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nicht genau.
Task.Run()
läuft der code auf einem anderen thread aus dem UI-thread (zumindest mit dem Standard -TaskScheduler
). Aber es wird nicht wirklich erstellen einen neuen thread, in den meisten Fällen verwenden Sie einen bereits vorhandenen thread aus demThreadPool
.Den Punkt
async
im Rahmen einer UI-Anwendung ist in der Lage, einfache Ausführung von code auf dem UI-thread nach und asynchrone Vorgang abgeschlossen ist.So, wenn Sie Ihre
method01Async
"erwartbaren", das heißt, machte es wieder einTask
:Könnte man dann erwarten Sie von der
btnAsync01_Click
Methode, wenn du es geschafft`, async:Diese Weise die Letzte Zeile der Methode wird nur ausgeführt, nachdem der
Task
immethod01Async
abgeschlossen. Und es wird ausgeführt, die auf dem UI-thread.In .Net 4.0, könnte man einen ähnlichen Effekt mit
ContinueWith()
undDispatcher.Invoke()
:Ich bin sicher, Sie werden Zustimmen, dass dies ist viel chaotischer und weniger lesbar.
Ja, du hast Recht.
Das Ergebnis ist sicherlich nicht das, was ich dachte, dein code tun soll. Die Letzte Zeile
btnAsync01_Click
, die ausgeführt wird, "nach method01Async", aber es wird nicht warten, bis dieTask
begann, die Methode abgeschlossen ist.As a side note, gibt es keine Notwendigkeit zu verwenden
async
in Ihremmethod01Async
. Rücksendung derTask
direkt (oder nicht, wenn Sie es behalten wollenvoid
-Rücksendung), wird die gleiche Arbeit:await
. Zwar mag es Sinn machen, den Einsatz im E-Mail-code, verwenden den threadpool effizienter zu gestalten.Nicht wirklich mit dem async-in jedem Fall, da bist du nicht warten auf den ersten Anruf. Hier ist, wie sollten Sie es tun:
Sobald Sie es ändern, um diese (wichtigen Teil
await method01Async()
in der Schaltfläche click-Ereignis, springt es wieder zurück, nachdem es beendet, und Ihre "nach ethod01Async:" text-log sollte zeigen, zehn Sekunden Verzögerung, genau wie Ihre "exit-method01Async" melden Sie sich in dermethod01Async
Methode.btnAsync01_Click
async
wenn Sie verwenden möchtenawait
in es.await
von einer Methode nicht getaggt mitasync
. Bearbeitete zu reflektieren. Dank svick.async
/await
ist, dass Sie wollen etwas tun, wenn es zurück, aber nicht bevor. In diesem Fall, IhreUpdateTxtLog("after ethod01Async: " + System.DateTime.Now);
würde Sie sofort ausführen, wenn Sie nichtawait
die Rückkehr derTask
. Mit meinem Beispiel würde es nur führen Sie nach dieTask
abgeschlossen, und es passiert immer noch auf einen anderen thread und es ist nicht blockiert, Ihre UI-thread.