引发异常时任务未处于故障状态 [英] Task not in a faulted state when an exception is thrown

查看:91
本文介绍了引发异常时任务未处于故障状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在以下示例中引发异常(假设engine.Send(...)引发异常)时,我似乎无法弄清楚为什么我的任务没有处于故障状态:

I can't seem to figure out why my task is not in a faulted state when an exception is thrown in the following sample (assume engine.Send(...) throws an exception):

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

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

if I do receiverTask.IsFaulted after the receiverTask.Wait() it returns false instead of true as I would expect.

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

I have been reading that I need to use something like the following construct:

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

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

But I can't seem to figure out how to integrate this into the sample code. Do I call this before the Start()? before the Wait()?

我希望调用程序以某种方式知道ReceiverTask抛出了异常并且失败了。

I would like the calling program to somehow be aware that the receiverTask has thrown an exception and failed. Any pointers?

推荐答案

如果我正确理解了此上下文,则可以忽略 .Start() 并使用 .Wait()有所不同。

If I correctly understand this context, you could leave out the .Start() and use .Wait() somewhat differently.

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

(I don't know what your engine.Send(someObject) method is, so I have to assume.)

让我们说您的方法返回一个布尔值(没关系,只是写点东西。

Let's say your method returns a bool (it doesn't matter, but just to write something down.

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

If it is synchronous, the returned Task could be:

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

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

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

If it is asynchronous, the returned Task could be:

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

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



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


(However, all these are blocking if there's no other async/await declaration).

计划任务后,可以定义一些延续条件以评估其状态。

如果任务位于某些错误状态(取消,中止等)。其 .IsCompleted 属性报告的 true ,但 .Status 属性不是 TaskStatus.RanToCompletion

Once your Task is scheduled, some Continuation condition can be defined to evaluate its status.
If the Task is in some faulty status (canceled, aborted etc.) its .IsCompleted property reports true, but the .Status property is not 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块:


But you might also use a Try/Catch block:

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

这篇关于引发异常时任务未处于故障状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆