Ich habe eine Weile versucht, etwas zu bekommen, von dem ich dachte, dass es einfach wäre, mit .NET 4.5 zu arbeiten
Ich möchte zwei lange laufende Aufgaben gleichzeitig starten und die
Ergebnisse auf die beste C # 4.5 (RTM) -Methode sammeln
Folgendes funktioniert, aber ich mag es nicht, weil:
- Ich möchte
Sleep
eine asynchrone Methode sein, damit es auchawait
andere Methoden können - Es sieht nur ungeschickt aus
Task.Run()
- Ich denke nicht, dass dies überhaupt neue Sprachfunktionen verwendet!
Arbeitscode:
public static void Go()
{
Console.WriteLine("Starting");
var task1 = Task.Run(() => Sleep(5000));
var task2 = Task.Run(() => Sleep(3000));
int totalSlept = task1.Result + task2.Result;
Console.WriteLine("Slept for a total of " + totalSlept + " ms");
}
private static int Sleep(int ms)
{
Console.WriteLine("Sleeping for " + ms);
Thread.Sleep(ms);
Console.WriteLine("Sleeping for " + ms + " FINISHED");
return ms;
}
Nicht funktionierender Code:
Update: Dies funktioniert tatsächlich und ist der richtige Weg, das einzige Problem ist das Thread.Sleep
Dieser Code funktioniert nicht, da der Aufruf zum Sleep(5000)
sofortigen Starten der ausgeführten Aufgabe Sleep(1000)
erst nach Abschluss ausgeführt wird. Dies ist wahr, obwohl es Sleep
ist async
und ich nicht benutzeawait
oder .Result
zu früh anrufe.
Ich dachte, es gibt vielleicht eine Möglichkeit, Task<T>
durch Aufrufen einer async
Methode eine Nicht-Ausführung zu erreichen , damit ich dann Start()
die beiden Aufgaben aufrufen kann, aber ich kann nicht herausfinden, wie ich Task<T>
durch Aufrufen einer asynchronen Methode eine erhalten kann.
public static void Go()
{
Console.WriteLine("Starting");
var task1 = Sleep(5000); // blocks
var task2 = Sleep(1000);
int totalSlept = task1.Result + task2.Result;
Console.WriteLine("Slept for " + totalSlept + " ms");
}
private static async Task<int> Sleep(int ms)
{
Console.WriteLine("Sleeping for " + ms);
Thread.Sleep(ms);
return ms;
}
quelle
task1.Result
nicht um,var task1 = Sleep(5000)
da Ihre Sleep-Methode ohne ein Schlüsselwort "wait" synchron ist.Antworten:
Sie sollten Task.Delay anstelle von Sleep für die asynchrone Programmierung verwenden und dann Task.WhenAll verwenden, um die Aufgabenergebnisse zu kombinieren. Die Aufgaben würden parallel ausgeführt.
quelle
quelle
Go
Methode des Aufrufers synchron ist, aber zwei unabhängige Aufgaben asynchron ausführen möchten (dh keine muss vor der anderen ausgeführt werden, aber beide müssen ausgeführt werden, bevor die Ausführung fortgesetzt wird), istTask.WaitAll
dies besser, und Sie tun dies nicht Das Schlüsselwort await wird nicht benötigt, daher muss die aufrufendeGo
Methode selbst nicht asynchron sein. Keiner der beiden Ansätze ist besser, es ist nur eine Frage Ihres Ziels.async void LongTask1() {...}
hat keine Task.Result-Eigenschaft. Verwenden Sie in diesem Fall Task ohne T :async Task LongTask1()
.Task<TResult> t1 = LongTask1();
und jetzt bekomme icht1.Result
.<TResult>
ist der Rückgabetyp Ihres Ergebnisses. Sie benötigen einereturn <TResult>
in Ihrer Methode, damit dies funktioniert.t1
und diet2
Variablen nicht möchtennew Task(...)
. Zum Beispiel :int int1 = 0; await Task.WhenAll(new Task(async () => { int1 = await LongTask1(); }));
. Ein Haken dieses Ansatzes ist, dass der Compiler nicht erkennt, dass die Variable zugewiesen wurde, und sie als nicht zugewiesen behandelt, wenn Sie ihr keinen Anfangswert geben.Während Ihre
Sleep
Methode asynchron ist,Thread.Sleep
ist dies nicht der . Die ganze Idee von Async besteht darin, einen einzelnen Thread wiederzuverwenden und nicht mehrere Threads zu starten. Da Sie die Verwendung eines synchronen Aufrufs von Thread.Sleep blockiert haben, funktioniert dies nicht.Ich gehe davon aus
Thread.Sleep
eine Vereinfachung dessen ist, was Sie tatsächlich tun möchten. Kann Ihre tatsächliche Implementierung als asynchrone Methode codiert werden?Wenn Sie mehrere synchrone Blockierungsanrufe ausführen müssen, schauen Sie woanders, denke ich!
quelle
var x = y()
und nichtvar x=await y()
odery().wait()
noch nicht Warten Sie den ganzen Weg, und wenn Async das nicht alleine erledigt, was soll ich dann tun? HINWEIS: y ist mit Async dekoriert, und ich erwarte, dass es alles innerhalb des Wann-Alls erledigt, nicht genau dort, wo es zugewiesen ist. BEARBEITEN: Ich habe gerade zu meinem Partner gesagt, lass es uns versuchenTask.Factory
, und er sagte, es hat funktioniert, wenn ich ausbreche Seite dieser KlasseUm diesen Punkt zu beantworten:
Sie können die
Sleep
Funktion möglicherweise folgendermaßen umschreiben :Wenn Sie diesen Code ausführen, wird Folgendes ausgegeben:
quelle
Es ist jetzt Wochenende !
quelle
Dieser Artikel hat viele Dinge erklärt. Es ist im FAQ-Stil.
Async / Await FAQ
Dieser Teil erklärt, warum
Thread.Sleep
auf demselben ursprünglichen Thread ausgeführt wird - was zu meiner anfänglichen Verwirrung führt.quelle