抛出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); }