2016-09-13 3 views
-3

Was ist der Unterschied zwischen diesen beiden asynchronen Methoden? Wenn nicht, in welcher Situation kann diese zwei Arten von Methoden anders sein?Was ist der Unterschied zwischen diesen beiden asynchronen Methoden?

Danke.

public async Task<int> MyMethod1Async() 
{ 
    return 1; 
} 

public async Task<int> MyMethod2Async() 
{ 
    return await new Task<int>(() => 1); 
} 
+2

Da es keinen Async-Code gibt, wird der erste nicht async .... –

+2

Ich stimme, diese Frage als off-topic zu schließen, weil die zugrunde liegende Frage, wie async/abwarten funktioniert, wertvoll ist, aber diese vereinfachte Form ist fehlerhaft. Sogar auf eine doppelte Frage zu zeigen ist schwierig, da eines der Beispiele nicht asynchron ist. – Guvante

+0

Wann führen Sie die Aufgabe tatsächlich in MyMethod2Async aus? Sie erstellen nur eine neue Aufgabe. – EJoshuaS

Antwort

1

einen Blick auf die beiden Methoden nehmen:

public async Task<int> MyMethod1Async() 
{ 
    return 1; 
} 

Diese synchron laufen wird, weil es keine „erwarten“ Operatoren sind darin - es 1 nur zurück, so dass es als nicht anders ist, wenn Sie das gerade getan hatte, folgende:

public int MyMethod1() 
{ 
    return 1; 
} 

die folgende Methode wahrscheinlich eine bessere Darstellung der Unterschied zwischen den verschiedenen „Typen“ von async ist:

public async Task<string> MyMethod1Async() 
    { 
     using (HttpClient client = new HttpClient()) 
     { 
      client.BaseAddress = new Uri("SomeBaseAddress"); 

      // This will return control to the method's caller until this gets a result from the server 
      HttpResponseMessage message = await client.GetAsync("SomeURI"); 

      // The same as above - returns control to the method's caller until this is done 
      string content = await message.Content.ReadAsStringAsync(); 

      return content; 
     } 
    } 

Code wie dieser erzeugt nicht unbedingt zusätzliche Threads (es sei denn, Microsoft hat diese speziellen Bibliotheksaufrufe so implementiert). Wie auch immer, wartet/async macht nicht erfordert die Erstellung zusätzlicher Threads; Es kann asynchron für denselben Thread ausgeführt werden.

Meine Standard-Illustration dieser Tatsache ist wie folgt: Angenommen, Sie gehen ein Restaurant mit 10 Personen. Wenn der Kellner vorbeikommt, ist die erste Person, die er um seine Bestellung bittet, nicht bereit; jedoch sind die anderen 9 Leute. So fragt der Kellner die anderen 9 Leute nach ihren Bestellungen und kommt dann zu dem ursprünglichen Typen zurück, in der Hoffnung, dass er bis dahin zur Bestellung bereit sein wird. (Es ist definitiv nicht der Fall, dass sie einen zweiten Kellner bekommen, der darauf wartet, dass der ursprüngliche Mann zur Bestellung bereit ist, und das würde wahrscheinlich sowieso nicht viel Zeit sparen). So funktioniert async/awaist in vielen Fällen (mit der Ausnahme, dass einige Task Parallel Library-Aufrufe wie Thread.Run (...), tatsächlich auf anderen Threads ausführen - in unserer Abbildung, bringen einen zweiten Kellner - also schau dir die Dokumentation an, welche das ist).

Das nächste Element, das Sie listet nicht funktionieren, weil Sie nur die Aufgabe erstellen, brauchen Sie nicht wirklich etwas mit ihm:

public async Task<int> MyMethod2Async() 
{ 
    return await new Task<int>(() => 1); 
} 

Ich gehe davon aus, dass Sie tatsächlich so etwas wie das zu tun gedenke folgende:

public async Task<int> MyMethod2Async() 
{ 
    return await Task.Run<int>(() => 1); 
} 

Dies wird den Lambda-Ausdruck in dem Thread-Pool, Rücksteuerung MyMethod2Async der Anrufer laufen, bis der Lambda-Ausdruck ein Ergebnis hat, und dann den Wert aus dem Lambda-Ausdruck zurück, sobald es ein Ergebnis hat.

Um es zusammenzufassen, ist der Unterschied, ob Sie laufen asynchron auf dem gleichen Thread (sonst er entspricht den ersten Mann am Tisch erzählt den Kellner wieder zu kommen, nachdem jeder bestellt hat) oder wenn Sie laufen die Aufgabe in einem separaten Thread.

Bei der Gefahr, die Dinge stark zu vereinfachen, sollten CPU-gebundene Aufgaben in der Regel asynchron auf einem Hintergrundthread ausgeführt werden.IO-gebundene Aufgaben (oder andere Fälle, in denen der Überfall meistens nur auf ein Ergebnis von einem externen System wartet) können jedoch häufig asynchron auf demselben Thread ausgeführt werden. Es wird nicht unbedingt eine Leistungsverbesserung geben, wenn man es auf einen Hintergrundthread setzt, anstatt es asynchron für denselben Thread auszuführen.

+0

Möchten Sie den Downvote erklären? – EJoshuaS

1

Das erste Verfahren liefert eine bereits abgeschlossene Aufgabe mit einem Result von 1. Die zweite Methode gibt eine Task<int> zurück, die nie abgeschlossen wird.

Verwandte Themen