抛出exception时,任务不处于故障状态

我似乎无法弄清楚为什么我的任务在以下示例中抛出exception时不处于故障状态(假设engine.Send(…)抛出exception):

var receiverTask = new Task(async () => { result = await Task.FromResult(engine.Send(someObject)); }); receiverTask.Start(); receiverTask.Wait(); 

如果我在receiverTask.Wait()之后执行receiverTask.IsFaulted ,它会返回false而不是true,正如我所期望的那样。

我一直在读,我需要使用类似以下构造的东西:

 receiverTask.ContinueWith(t => { /* error handling */ }, TaskContinuationOptions.OnlyOnFaulted); 

但我似乎无法弄清楚如何将其集成到示例代码中。 我在Start()之前调用它吗? 在Wait()之前?

我希望调用程序以某种方式意识到receiverTask已抛出exception并失败。 有什么指针吗?

如果我正确理解了这个上下文,你可以省略.Start()并使用.Wait()

(我不知道你的engine.Send(someObject)方法是什么,所以我必须假设。)

假设你的方法返回一个bool(这没关系,但只是写下来。

如果它是同步的,则返回的Task可以是:

  Task receiverTask = Task.Run(async () => await Task.FromResult(engine.Send(someObject))); 

要么

  Task receiverTask = Task.Factory.StartNew(async delegate { bool _result = await Task.FromResult(engine.Send(someObject)); return _result; }, TaskScheduler.Default).Unwrap(); 

如果它是异步的,则返回的Task可以是:

  Task receiverTask = Task.Run(async () => await engine.Send(someObject)); 

要么

  Task receiverTask = Task.Factory.StartNew(async delegate { bool _result = await engine.Send(someObject); return _result; }, TaskScheduler.Current).Unwrap(); 

(但是,如果没有其他异步/等待声明,所有这些都会阻塞)。

安排任务后,可以定义一些Continuation条件来评估其状态。
如果任务处于某种故障状态(取消,中止等),则其.IsCompleted属性报告为true ,但.Status属性不是TaskStatus.RanToCompletion

  receiverTask.ContinueWith(t => { //Continue on faulted Console.WriteLine(receiverTask.GetAwaiter().IsCompleted); if (receiverTask.IsFaulted) Console.WriteLine(receiverTask.Exception.InnerExceptions[0].Message); }, TaskContinuationOptions.OnlyOnFaulted).Wait(0); receiverTask.ContinueWith(t => { //Continue on canceled Console.WriteLine(receiverTask.GetAwaiter().IsCompleted); if (receiverTask.IsCanceled) Console.WriteLine(receiverTask.Exception.InnerExceptions[0].Message); }, TaskContinuationOptions.OnlyOnCanceled).Wait(0); receiverTask.ContinueWith(t => { //Standard behaviour Console.WriteLine(receiverTask.GetAwaiter().IsCompleted); Console.WriteLine(receiverTask.Status.ToString()); }, TaskContinuationOptions.None).Wait(); //This writes only if no errors have been raised if (receiverTask.Status == TaskStatus.RanToCompletion) Console.WriteLine("Completed: {0} Result: {1}", receiverTask.GetAwaiter().IsCompleted, receiverTask.Result); 

但您也可以使用Try / Catch块:

  try { receiverTask.Wait(); if (receiverTask.Status == TaskStatus.RanToCompletion) Console.WriteLine("Completed: {0} Result: {1}", receiverTask.GetAwaiter().IsCompleted, receiverTask.Result); } catch (Exception) { receiverTask.ContinueWith(t => { //With continuation if (receiverTask.IsFaulted) Console.WriteLine(receiverTask.Exception.InnerExceptions[0].Message); }, TaskContinuationOptions.OnlyOnFaulted); //or without //if (receiverTask.IsCanceled) //Console.WriteLine(receiverTask.Exception.InnerExceptions[0].Message); }