2016-10-14 4 views
-1

Ich bekomme, dass ich in einer async markierte Methode warten muss, um es asynchron zu machen, aber ich bekomme nicht, wie man das Loch wirklich beendet, das es macht.Wie schreibe/beende ich eine asynchrone Methode in C#?

static async void Example() 
{ 
    int t = await getIntAsync(); 
    WriteLine($"computer: {t}"); 
} 

Da getIntAsync markiert async ich in diesem Verfahren zu erwarten haben oder ich erhalte eine Warnung aus. Aber oh nein, in der Methode, auf die ich in getIntAsync warte, muss ich das als asynchron markieren, und wenn es nicht darauf ankommt, bekomme ich eine Warnung. Und so weiter und so weiter bis zur Unendlichkeit. Wie kann ich es einfach stoppen?

Ich habe ein paar Leute

await Task.Delay(1000); 

In meinem Code zu setzen, mir zu sagen habe, aber ich weiß die Antwort nicht so muffig sein kann eine Verzögerung von einer Sekunde in alle Code meiner Produktion setzen.

Ein paar andere gesagt eine Aufgabe, Verfahren es wie

static Task task() 
{ 
    //code 
} 

zu beenden Aber es sei denn, ich kennzeichnen, dass async es die gleiche Warnung wirft, die mich in diese Verwirrung bekam. Ich weiß,

Technisch funktioniert es, aber wieder scheint das zu viel von einem Code-Geruch zu haben über die gesamte Produktion.

ich es einfach nicht bekommen ...

EDIT: Weil es wurde gefragt. Ich weiß, dass es eine sehr triviale Methode ist, aber es ist auch nur eine Übung, die ich benutze.

static async Task<int> getIntAsync() 
    { 

     Console.Write("Enter the number: "); 
     int n = int.Parse(Console.ReadLine()); 
     return n; 

    } 
+1

Können Sie zeigen, was Sie _actually_ versuchen zu erreichen? Wenn Sie keine wirklich asynchrone Methode darin haben, _why_ möchten Sie die Methode der höheren Ebene überhaupt asynchron machen? –

+0

[check msdn] (https://msdn.microsoft.com/en-us/library/mt674882.aspx) – inan

+3

Wenn Sie nichts zu erwarten haben, markieren Sie die Methode nicht als async. Einfach genug. –

Antwort

0

Das folgende ist erforderlich (async Schlüsselwort ist erforderlich, und so ist die await, ist es einfach Best Practice):

  1. Das Async Stichwort
  2. Die Await Stichwort
  3. Einige Prozess, den Sie möchte unabhängig arbeiten, während der asynchrone Prozess läuft.
  4. Normalerweise kommt der Rückgabewert von Ihrer Warteaufgabe (die das Endloch ausfüllen sollte).

Hier wird beispielsweise ein Stream verwenden,

async Task<string> GetStringFromReaderAsync() 
{ 
    Streamreader sr = new StreamReader("filename.txt"); 

    Task<string> getStringTask = sr.ReadLineAsync("filepath"); 

    //Allow user to continue with some other work. 
    DoFileLookup(); 

    string result = await sr.getStringTask(); 

    return result.ToString(); 

} 

Weitere Informationen hier: https://msdn.microsoft.com/en-us/library/system.io.streamreader.readlineasync(v=vs.110).aspx

Mehr über Async und Await: https://msdn.microsoft.com/en-us/library/mt674882.aspx

+0

Aber wie geht ReadLineAsync damit um? Was macht es, um das Loch zu verstopfen? Worauf wartet es und wie beendet es seine Wartekette? Das ist was ich nicht bekomme. – meeheecaan

+0

Ich bitte um Entschuldigung bitte sehen Sie die Antwort erneut an, 'string result = await.ReadLineAsync()', sollte 'string result = sr.getStringTask();' sein – JDavila

+0

Also ist die getStringTask nur die asynchrone Aufgabe, die den aktuellen Thread ausführt, Erlauben der Operation, während dieser Thread ausgeführt wird. Das Loch ist verstopft, was ich denke, du meinst, das Ergebnis des Wartens ist, wenn dieser Thread abgeschlossen oder bearbeitet ist. Sobald dieser Thread beendet ist, endet die "Wartekette" und gibt Ihnen das Ergebnis, auf das der Benutzer gewartet hat, während er andere Operationen ausgeführt hat. – JDavila

4

Was hier ist verwirrend ist, dass Sie dies nicht tun wirklich etwas tun asynchron. Console.ReadLine() ist eine synchrone Methode. Einfach irgendwo async oder await eingeben, macht das nicht magisch asynchron.

Da dieser Code nur zum Testen und Lernen, eine Möglichkeit, es zu machen asynchron ist es mit Task.Run() auf einem anderen Thread zu setzen (ich würde das Produkt in der Produktion Code für viele Fälle nicht den Eindruck erwecken):

static Task<int> getIntAsync() 
{ 
    Console.Write("Enter the number: "); 
    return Task.Run(() => int.Parse(Console.ReadLine()); 
} 

Es wird kein Schlüsselwort async benötigt, da Sie nicht auf etwas warten. Sie geben einfach eine zurück, die abgeschlossen ist, wenn der Benutzer einen Wert eingegeben hat und dieser Wert analysiert wurde.

Und Ihre Example() Methode funktioniert dann wie folgt aus:

static async void Example() 
{ 
    int t = await getIntAsync(); 
    WriteLine($"computer: {t}"); 
} 

Wenn die await getroffen wird, wird der Steuerablauf zu dem Anrufer und der Rest dieser Methode (die Zuordnung zu t und dem Aufruf von Console.WriteLine() zurück) sind als Fortsetzung geplant, die ausgeführt wird, wenn die Task<int> zurückgegeben von getIntAsync() beendet ist.

0
static async Task<int> getIntAsync() 
{ 

    Console.Write("Enter the number: "); 
    int n = int.Parse(Console.ReadLine()); 
    return n; 
} 

Diese synchron laufen wird als nicht dort erwarten Aussage ist und keine erwartete Anruf zu einem Asynchron-Methode

die allgemeine Idee ist diese

public async Task<int> ExecuteAsync() //Method return type is Task<int> 
    { 
     // Error: return type is not int. Return type is Task<int> 
     return db.SaveChangesAsync(); 

     // OK: returns a task handle that you can await on in you code that called ExecuteAsync() 
     // you thread continues processing in your calling function until you try to read the value from this return statement. 
     return await db.SaveChangesAsync(); 

     // Ok. Your Thread leaves here and returns when result available. 
     // no further Processing done in calling function 
     return db.SaveChangesAsync().Result; 

     // Ok. This is not required in this case, 
     // but if you have an async method that has multiple return points, 
     // and one of them does not depend on an async method, you can wrap 
     // the output e.g. return await Task.FromResult(0); 
     return await Task.FromResult(db.SaveChangesAsync().Result); 

     return 0; //also ok. 
    } 

Hinzufügen auf die andere Antwort unten.

Dieser Ansatz macht etwas, das synchron ausgeführt wird, um in eine Aufgabe eingeschlossen zu werden. Allerdings sollten Sie dies nie tun (es sei denn, Sie wissen natürlich, was Sie tun), da dies einen anderen Thread hervorbringt. Ein Anwendungsfall, bei dem ich dies verwendet habe, ist das Auslagern in Webservern, aber ansonsten ist es generell eine schlechte Idee. Obwohl Sie vielleicht mit der Absicht begonnen haben, die maximale Nutzung eines einzelnen Threads zu nutzen, haben Sie nun mit zwei Threads gearbeitet.

Verwandte Themen