2016-05-20 6 views
1

Nehmen wir an, dass ich zwei Methoden haben, so ...Unterschied in Task-Verarbeitung

public void MyMethod() 
{ 
    // do some stuff 
} 

public Task MyMethodAsync() 
{ 
    //run MyMethod asynchronously 
} 

Was ist die beste Form, die sie in asynchroner Weise auszuführen?

Gefällt Ihnen dieses

public Task MyMethodAsync() 
{ 
    return Task.Run(() => MyMethod()); 
} 

oder so?

public async Task MyMethodAsync() 
{ 
    await Task.Run(() => MyMethod()); 
} 
+2

Das ist nicht wirklich async, es läuft nur auf einem anderen Thread. Es ist besser, wenn Sie in Ihrer asynchronen Methode, die Sie erwarten, tatsächliche E/A-gebundene Arbeit haben, und dann können Sie eine davon synchronisieren. – juharr

+0

Behalten Sie einfach die 'Async'-Methode bei, und lassen Sie dann den Verbraucher entscheiden, ob er darauf warten möchte. Es ist nur Zucker, der den anderen hält. – Jonesopolis

+1

Ich würde MyMethodAsync überhaupt nicht machen, sondern den Aufrufer den 'Task.Run (() => myClass.MyMethod()); -Aufruf machen lassen. Es ist keine gute Methode, "[fake async] (http://blog.stephencleary.com/2013/10/taskrun-etiquette-and-proper-usage.html)" -Methoden zu erstellen. –

Antwort

3

Sie sollten lesen Stephen Cleary's tutorial wann - und wann nicht - zu verwenden Task.Run.

Kurze Antwort: Verwenden Sie nicht Task.Run, um eine gefälschte asynchrone Methode zu erstellen. Wenn Ihr Code nicht wirklich async ist, dann lassen Sie den Aufrufer entscheiden, ob er einen Thread (oder was auch immer) verwenden soll, um Ihren Code aufzurufen.

+0

Danke ... Hilft sehr .... – Jedi31

1

Es ist besser, anders herum zu gehen. Erstellen Sie die innere Aufgabe als async und lassen Sie dann alle Anrufer, die die async-Methode nicht verwenden können, die asynchrone Methode intern verwenden und darauf warten.

public void MyMethod() 
{ 
    MyMethodAsync().Wait(); 
} 

public async Task MyMethodAsync() 
{ 
    // do some stuff 
} 

Beide Methoden machen nichts wirklich async. Bei Async geht es nicht darum, etwas im Hintergrund auszuführen, das ist der Bereich der Task-Bibliothek (oder parallele Erweiterungen oder Threading usw.). Bei Async geht es darum, einen einzelnen Thread für mehrere Dinge wiederzuverwenden, wenn es nichts Besseres zu tun gibt - was die Sache besser skalierbar macht. Wenn Sie eine Pseudo-Async-Methode ausführen, wird nur die Tatsache ausgeblendet, dass Sie einen NEUEN Thread verwenden, anstatt denselben Thread erneut zu verwenden, wodurch das System LESS skalierbar wird.

Um dies zu tun, müssen echte Async-Prozesse auf diese Weise von innen nach außen geschrieben werden. Alles (oder zumindest die Teile, die zeitaufwendig sind) müssen sich auf asynchrone Methoden stützen, die das tun. Zum Beispiel, einen SOAP-Aufruf zu machen, bei dem der Thread im Grunde nur im Leerlauf bleibt, während er darauf wartet, dass der Aufruf zurückkehrt, oder einen Datenbankaufruf oder Datei-I/O. Async erlaubt diesem Thread, etwas anderes zu tun, anstatt nur im Leerlauf zu sitzen.

+1

offensichtlich von jemandem, der ratlos über was async eigentlich ist, downvoted ist. Naja. –

+0

Ich habe verstanden, was du sagen wolltest ... Ich weiß nicht, ob ich das umsetzen werde, aber ich habe es verstanden ...;) – Jedi31

+0

Wenn ich einen liefern muss, dann setze ich auch die Sync-Version einer nativ-asynchronen Methode ein. – moswald

1

Im Falle Ihrer ersten Methode können Sie auch eine Aufgabe in einem separaten Thread haben. Es ist nicht wirklich asynchron, weil Sie nicht klar darauf warten, dass der Thread endet, um einen neuen Prozess zu starten. Wenn Sie dies aufgerufen haben, würde es fortgesetzt, bevor die Aufgabe abgeschlossen war.

public Task MyMethodAsync() 
{ 
    return Task.Run(() => MyMethod()); 
} 

Blick auf die zweite Version. Sie warten darauf, dass die Aufgabe abgeschlossen wird, damit Sie etwas tun können, ohne den aktuellen Thread hochzuhalten.

public async Task MyMethodAsync() 
{ 
    await Task.Run(() => MyMethod()); 
    DoMoreWork(); 
    //Do something following the completion of the task 
    //without binding up the calling thread, but actually complete it on that thread. 
}