erwartete ich the following code haben, die auf .NET Standard-2.0 ausgeführt wird:Async Await und ContinueWith funktioniert nicht wie
public static Task<JobResult> TryRunAsync(this IJob job,
CancellationToken cancellationToken = default(CancellationToken))
{
return job.RunAsync(cancellationToken)
.ContinueWith(t => {
if (t.IsFaulted)
return JobResult.FromException(t.Exception.InnerException);
if (t.IsCanceled)
return JobResult.Cancelled;
return t.Result;
});
}
Und wir bemerkt, es war nicht wie erwartet ausgeführt wird. Wir dachten, dass, wenn Sie den Aufruf von TryRun erwarteten, es immer die Fortsetzung aufrufen würde, die die Ausnahme/Löschung behandeln und ein Job-Ergebnis zurückgeben könnte. Wir hatten gehofft, die Menge an asynchronen Zustandsmaschinen zu reduzieren ... Das ist jedoch nicht der Fall, es explodiert einfach. Hier ist eine kleinere Probe (eine neue .net Kern 2.0 Konsole app erstellen und fügen Sie den folgenden:.
using System;
using System.Threading.Tasks;
namespace ConsoleApp4
{
public class Program
{
public static async Task Main()
{
// works
await DoStuff();
Console.ReadKey();
// blows up
await TryRun();
Console.ReadKey();
}
public static Task DoStuff()
{
return Method()
.ContinueWith(t => Throws())
.ContinueWith(t => {
if (t.IsFaulted)
Console.WriteLine("Faulted");
else if (t.IsCompletedSuccessfully)
Console.WriteLine("Success");
});
}
public static Task Method()
{
Console.WriteLine("Method");
return Task.CompletedTask;
}
public static Task TryRun()
{
return Throws()
.ContinueWith(t => {
if (t.IsFaulted)
Console.WriteLine("Faulted");
else if (t.IsCompletedSuccessfully)
Console.WriteLine("Success");
});
}
public static Task Throws()
{
Console.WriteLine("Throws");
throw new ApplicationException("Grr");
}
}
}
Sie müssen möglicherweise <LangVersion>Latest</LangVersion>
In Ihrem csproj
UPDATE
Am Ende haben wir gehen mit dem folgenden Code:
public static Task<JobResult> TryRunAsync(this IJob job,
CancellationToken cancellationToken = default(CancellationToken))
{
var tcs = new TaskCompletionSource<JobResult>(null);
try {
var task = job.RunAsync(cancellationToken);
task.ContinueWith((task2, state2) => {
var tcs2 = (TaskCompletionSource<object>)state2;
if (task2.IsCanceled) {
tcs2.SetResult(JobResult.Cancelled);
} else if (task2.IsFaulted) {
tcs2.SetResult(JobResult.FromException(task2.Exception));
} else {
tcs2.SetResult(JobResult.Success);
}
}, tcs, cancellationToken);
} catch (Exception ex) {
tcs.SetResult(JobResult.FromException(ex));
}
return tcs.Task;
}
Kommentare sind nicht für längere Diskussion; Diese Konversation wurde [in den Chat verschoben] (http://chat.stackoverflow.com/rooms/161464/discussion-on-answer-by-servy-async-mait-and-continuewith-not-working-as-expect) . – Andy