は、次のコードを考えてみましょう:ContinueWith()を使用して元の例外を取得する方法?
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");
}
}
}
これは、次のような出力が得られます
Exception received: A task was canceled.
を私の質問は簡単です:どのように私は、元のInvalidOperationException("TEST");
ではなくSystem.Threading.Tasks.TaskCanceledException
で入手できますか?
.ContinueWith()
部分を削除すると、これは期待通りに機能し、その場合の出力はException received: TEST
です。答えに
(また、この例では、純4.5を使用していますが、元のコードは、.NET 4.0を使用しなければならないことに注意してください)
SOLUTION
おかげで、これが今取り組んでいます。私は以下のソリューションを選択しました - 私は、元のタスクと継続タスクの両方で待機するために必要な:あなたは後でそれがException
財産だ調べることができるようにTask.Run(() => throwExceptionAfterOneSecond())
への参照を格納する必要が
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");
}
}
}
「TaskContinuationOptions.NotOnFaulted」を削除するにはどうすればよいですか? –
@KirillShlenskiyこれを行うと、 'Task.WaitAll()'から何も例外が発生しません。 –
内部タスクではなく、継続タスクを待っています。後で継続を追加してください: 'tasks [0] .ContinueWith(...)'。 –