Betrachten Sie den folgenden Code ein:Wie bekomme ich die ursprüngliche Ausnahme, wenn ich ContinueWith() verwende?
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
static class Program
{
static void Main()
{
var tasks = new Task[1];
tasks[0] = Task.Run(() => throwExceptionAfterOneSecond())
.ContinueWith(task => {
Console.WriteLine("ContinueWith()"); }, TaskContinuationOptions.NotOnFaulted);
try
{
Task.WaitAll(tasks);
}
catch (AggregateException ex)
{
Console.WriteLine("Exception received: " + ex.InnerExceptions.Single().Message);
}
}
static void throwExceptionAfterOneSecond()
{
Thread.Sleep(1000);
throw new InvalidOperationException("TEST");
}
}
}
Dies ergibt die folgende Ausgabe:
Exception received: A task was canceled.
Meine Frage ist einfach: Wie komme ich an der ursprünglichen InvalidOperationException("TEST");
eher als ein System.Threading.Tasks.TaskCanceledException
?
Beachten Sie, dass wenn Sie den .ContinueWith()
Teil entfernen, funktioniert dies wie erwartet und die Ausgabe in diesem Fall ist Exception received: TEST
.
(Beachten Sie auch, dass in diesem Beispiel verwendet, ist .NET 4.5, aber die ursprüngliche Code muss .NET 4.0 verwenden)
SOLUTION
Dank der Antworten, das funktioniert jetzt. Ich entschied mich für die folgende Lösung - ich brauchte auf die ursprüngliche Aufgabe sowohl AND Aufgabe der Fortsetzung warten:
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
static class Program
{
static void Main()
{
var tasks = new Task[2];
tasks[0] = Task.Run(() => throwExceptionAfterOneSecond());
tasks[1] = tasks[0].ContinueWith(task => {
if (task.Status == TaskStatus.RanToCompletion)
Console.WriteLine("ContinueWith()"); });
try
{
Task.WaitAll(tasks);
}
catch (AggregateException ex)
{
Console.WriteLine("Exception received: " + ex.InnerExceptions.Single().Message);
}
Console.WriteLine("Done.");
}
static void throwExceptionAfterOneSecond()
{
Thread.Sleep(1000);
throw new InvalidOperationException("TEST");
}
}
}
Wie wäre es, 'TaskContinuationOptions.NotOnFaulted' zu entfernen? –
@KirillShlenskiy Wenn Sie das tun, erhalten Sie keine Ausnahme von 'Task.WaitAll()'. –
Sie warten auf die Fortsetzung Aufgabe, anstatt die innere Aufgabe. Fügen Sie die Fortsetzung später hinzu: 'tasks [0] .ContinueWith (...)'. –