Was ist der richtige Weg, um Aufgaben bei der Rückgabe einer Aufgabe zu verketten?
Ich bin so so mit mit Aufgaben in C#, aber ich verwirrt, wenn ich versuche, um wieder eine Aufgabe aus einer Methode und die Methode werden mehrere Aufgaben in sich. So habe ich meine Methode, spin-up eine neue Aufgabe und mache dann alle nacheinander innerhalb von es? Es ist schwer zu wickeln Sie meinen Kopf herum, tun es alle mit .ContinueWith()
Beispiel:
public Task<string> GetSomeData(CancellationToken token)
{
return Task.Factory.StartNew(() =>
{
token.ThrowIfCancellationRequested();
var initialData = GetSomeInteger(token).Result;
return GetSomeString(initialData, token).Result;
});
}
public Task<int> GetSomeInteger(CancellationToken token)
{
return Task<int>.Factory.StartNew(() =>
{
return 4;
}, token);
}
public Task<string> GetSomeString(int value, CancellationToken token)
{
return Task<string>.Factory.StartNew(() =>
{
return value.ToString();
}, token);
}
Ich bin mir nicht sicher wie sonst zu schreiben, diese Methode zu machen, verwenden Sie Aufgaben richtig. Ich denke, ich fühle mich einfach wie es sein sollte .ContinueWith in es oder etwas.
Möglich beheben??
public Task<string> GetSomeData(CancellationToken token)
{
return GetSomeInteger(token).ContinueWith((prevTask) =>
{
return GetSomeString(prevTask.Result, token);
}, token).Unwrap();
}
InformationsquelleAutor der Frage Travyguy9 | 2012-08-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Im Allgemeinen, ist es oft am besten, um zu versuchen zu vermeiden, dreht neue Aufgaben wenn Sie bereits arbeiten mit dem task-basierten Methoden. Verkettung von Aufgaben statt blockieren explizit reduziert den overhead des Systems, wie es wird nicht verhindern, dass ein ThreadPool-thread gebunden warten.
Dass gesagt wird, oft ist es einfacher, nur block, wie Sie tun.
Beachten Sie, dass C# 5 macht dies viel einfacher und bietet eine API, die Ihnen das beste von beiden:
Edit nach update:
Angesichts der neuen code, gibt es nicht eine einfache Möglichkeit, diese Kette direkt mit
ContinueWith
. Es gibt ein paar Optionen. Sie können Auspacken zu konvertieren, dieTask<Task<string>>
würden Sie schaffen, sprich:Alternativ können Sie die unwrapping sich aus mit
TaskCompletionSource<T>
:Dies ermöglicht es, den gesamten Prozess zu arbeiten, ohne die Erstellung einer neuen Aufgabe (die knüpft ein threadpool-thread), und ohne jemals blockieren.
Beachten Sie, dass Sie würde wahrscheinlich hinzufügen möchten Fortsetzungen über die Löschung und die Nutzung tcs.SetCancelledwenn eine Stornierung angefordert wurde, sowie.
InformationsquelleAutor der Antwort Reed Copsey
Hier ist eine Erweiterung Methode, die ich gebaut um dieses Problem zu lösen. Funktioniert in .Net 4+
InformationsquelleAutor der Antwort Kraig McConaghy
Ja, alles läuft nacheinander in Ihre Haupt-Aufgabe. Dies ist, weil Aufruf der Result-Eigenschaft blockiert den aktuellen thread bis der Wert zurückgegeben hat.
InformationsquelleAutor der Antwort davenewza