2012-11-14 10 views
10

Was wäre die beste Alternative für das erwarten Schlüsselwort in .NET 4.0? Ich habe eine Methode, die nach einem asynchronen Vorgang einen Wert zurückgeben muss. Ich habe festgestellt, dass die Methode wait() den Thread vollständig blockiert, wodurch die asynchrone Operation unbrauchbar wird. Welche Optionen habe ich, um den asynchronen Vorgang auszuführen, während der UIhread weiterhin freigegeben wird?Erwarten Sie eine Alternative in .NET 4.0?

+1

Verwendung erwarten, aber in der richtigen Weise, denke ich. Sie haben etwas Code? – lboshuizen

+3

Ist es akzeptabel, VS2012 mit C# 5.0 beim Targeting von .net 4.0 zu verwenden? Siehe [Verwenden von async-await auf .net 4] (http://stackoverflow.com/questions/9110472/using-async-await-on-net-4) – CodesInChaos

+0

@CodesInChaos Für Mitarbeiter, nein :). – Dante

Antwort

4

Ich denke, Ihre grundlegenden Optionen

sind

Der einfachste Weg, wahrscheinlich die Installation unter Verwendung von Asynchrones CTP. Soweit ich weiß, erlaubt die Lizenz kommerzielle Nutzung. Es patcht den Compiler und kommt mit einer 150kb DLL, die Sie in Ihr Projekt aufnehmen können.

Sie können Task und .ContinueWith() verwenden. Das heißt aber, dass Sie sich mit Ausnahme- und Ablaufkontrolle etwas anstrengen müssen.

Aufgaben sind ein funktionales Konstrukt. Deshalb passt ContinueWith() nicht gut mit imperativen Konstrukten wie for Loops oder try-catch Blöcken. Daher wurden async und await eingeführt, damit der Compiler uns helfen kann.

Wenn Sie diese Unterstützung des Compilers nicht haben können (d. H. Sie verwenden. NET 4.0), ist Ihre beste Wette, die TAP zusammen mit einem funktionalen Rahmen zu verwenden. Reactive Extensions ist ein sehr guter Rahmen um asynchrone Methoden zu behandeln.

Googeln Sie einfach für "reaktive Erweiterungen Tasks", um loszulegen.

1

Sie könnten ein Verhalten wie await mit den yield Coroutinen implementieren, ich benutze dies in nicht-4.5-Code. Sie benötigen eine YieldInstruction Klasse, die von der Methode abgerufen wird, die Asynchron ausgeführt werden soll:

public abstract class YieldInstruction 
{ 
    public abstract Boolean IsFinished(); 
} 

Dann müssen Sie einige Implementierungen des YieldInstruction (ae TaskCoroutine, die eine Aufgabe übernimmt) und es auf diese Weise (Pseudo-Code) verwenden:

public IEnumerator<YieldInstruction> DoAsync() 
{ 
    HttpClient client = ....; 
    String result; 
    yield return new TaskCoroutine(() => { result = client.DownloadAsync(); }); 
    // Process result here 
} 

Jetzt benötigen Sie einen Scheduler, der die Ausführung der Anweisungen behandelt.

for (Coroutine item in coroutines) 
{ 
    if (item.CurrentInstruction.IsFinished()) 
    { 
     // Move to the next instruction and check if coroutine has been finished 
     if (item.MoveNext()) Remove(item); 
    } 
} 

Wenn WPF oder WinForms-Anwendungen entwickeln, sind Sie auch in der Lage alle Invoke Anrufe zu vermeiden, wenn Sie die Koroutinen zum richtigen Zeitpunkt aktualisieren. Sie könnten auch in der Lage sein, die Idee zu erweitern, um Ihr Leben noch einfacher zu machen. Beispiel:

public IEnumerator<YieldInstruction> DoAsync() 
{ 
    HttpClient client = ....; 
    client.DownloadAsync(..); 

    String result; 
    while (client.IsDownloading) 
    { 
     // Update the progress bar 
     progressBar.Value = client.Progress; 
     // Wait one update 
     yield return YieldInstruction.WaitOneUpdate; 
    } 
    // Process result here 
}