Ich muss etwas wie ein kalt beobachtbares Objekt in RxJS implementieren (nur ein Standard-Observable). Ich muss eine Async-Methode innerhalb einer Aufgabe aufrufen, die ich selbst über Konstruktor (new Task()) erstelle. Ich muss dies implementieren, da ich vor dem Ausführen von asynchronem Code einige Dinge tun möchte, die sehr spezifisch für mein Projekt sind. Ich möchte also eine Aufgabe erhalten, die noch nicht gestartet ist und die ich später manuell starten kann.So rufen Sie eine asynchrone Methode in einer manuell erstellten Aufgabe auf?
Bis jetzt kam ich zu der folgenden Entscheidung und zu meiner Überraschung funktioniert es nicht!
class Program
{
static void Main(string[] args)
{
var task1 = CallApi(() => t.Go());
var task2 = CallApi2(() => t.Go());
task1.Start();
task2.Start();
}
public static Task<T> CallApi<T>(Func<Task<T>> function)
{
if (function == null)
{
throw new ArgumentNullException(nameof(function));
}
return new Task<Task<T>>(async() =>
{
return await function();
}).Unwrap();
}
public static Task<T> CallApi2<T>(Func<Task<T>> function)
{
if (function == null)
{
throw new ArgumentNullException(nameof(function));
}
var tcs = new TaskCompletionSource<T>();
var resultTask = new Task<Task<T>>(() =>
{
var t = function();
t.ContinueWith(
task => {
tcs.SetResult(task.Result);
},
TaskContinuationOptions.OnlyOnRanToCompletion
);
t.ContinueWith(
task => {
tcs.SetCanceled();
},
TaskContinuationOptions.OnlyOnCanceled
);
t.ContinueWith(
task => {
tcs.SetException(task.Exception);
},
TaskContinuationOptions.OnlyOnFaulted
);
return tcs.Task;
});
return resultTask.Unwrap();
}
}
Es scheint, dass Abwickelwerkzeug Aufruf oder mit TaskCompletionSource eine Aufgabe in einem WaitingForActivation Staat schafft. Und das Aufrufen der Start-Methode für Aufgaben in diesem Zustand führt mich zu der Ausnahme, die besagt:
Start möglicherweise nicht auf eine Versprechen-Stil-Task aufgerufen werden.
So ist es sehr wahrscheinlich, dass .NET besondere Art von Aufgaben unterscheidet - Versprechen Stil Aufgaben.
Zusammenfassend meine Fragen sind:
Was bedeuten diese Versprechen Stil Aufgaben?
Wie kann ich tun, was ich tun möchte?
Auspacken tut nicht, was Sie denken, dass es tut. Ihre kalten Aufgaben können nie gestartet werden, Sie haben nach dem Aufruf von Unwrap() den Verweis auf sie verloren. Denken Sie an die Funktion ist einfach implementiert als öffentliche statische asynchrone Task Unwrap (diese Aufgabe > Aufgabe) {Rückkehr warten Aufgabe; } 'Die interne 'await task' wird niemals abgeschlossen, da Sie keine Möglichkeit mehr haben, diese äußere Aufgabe zu starten. –
@ScottChamberlain Ich habe nicht darüber nachgedacht. Deshalb habe ich versucht, bei der von Unwrap zurückgegebenen Aufgabe Start aufzurufen. – Dobby007