当前位置: 首页 > 知识库问答 >
问题:

如何从取消的任务中获取内部异常?

公良同
2023-03-14
var cancellationTokenSource = new CancellationTokenSource();

var task1 = Task.Factory.StartNew(
                () =>
                    {
                        try
                        {
                            // Do work 
                        }
                        catch (Exception exception)
                        {                              
                            cancellationTokenSource.Cancel();

                            // rethrow the error
                            throw;
                        }     
                    },
                cancellationTokenSource.Token,
                TaskCreationOptions.None,
                taskScheduler); 
return task3 =
                Task.Factory.ContinueWhenAll(
                    new[] { task1, task2 },
                    tasks =>
                        {                           
                           // Do work
                        },
                cancellationTokenSource.Token,
                TaskContinuationOptions.None,
                this.taskScheduler).Unwrap();

共有1个答案

百里君博
2023-03-14

使用Async/Await和常规异常处理怎么样?不过,它需要。Net4.5。类似于这样的内容(我不知道任务之间必须如何交互,因此您的代码最终看起来可能完全不同):

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{

    class Program
    {
        static void Main(string[] args)
        {
            new MyClass().RunAsyncMethods();
            Console.ReadLine();

        }

        public class MyClass
        {
            public async void RunAsyncMethods()
            {
                try
                {
                    var cancellationTokenSource = new CancellationTokenSource();

                    var task1 = RunFirstTaskAsync(cancellationTokenSource);
                    var task2 = RunSecondTaskAsync(cancellationTokenSource);

                    await Task.WhenAll(task1, task2);
                    await RunThirdTaskAsync(cancellationTokenSource);
                    Console.WriteLine("Done");
                }
                catch (Exception exc)
                {
                    Console.WriteLine(exc.Message);
                }
            }

            public Task RunFirstTaskAsync(CancellationTokenSource cancelSource)
            {
                return Task.Run(() =>
                {
                    try
                    {
                        Console.WriteLine("First Task is Running");
                        throw new Exception("Error happened in first task");
                    }
                    catch (Exception exception)
                    {
                        cancelSource.Cancel();

                        throw;
                    }
                },
                    cancelSource.Token);
            }

            public Task RunSecondTaskAsync(CancellationTokenSource cancelSource)
            {
                return Task.Run(
                    () =>
                    {
                        Console.WriteLine("Second Task is Running");
                    },
                    cancelSource.Token);
            }

            public Task RunThirdTaskAsync(CancellationTokenSource cancelSource)
            {
                return Task.Run(
                    () =>
                    {
                        Console.WriteLine("Third Task is Running");
                    },
                    cancelSource.Token);
            }
        }
    }
}

更新:我更新了代码以使用Whenall。

Update:更新代码,使用Task.Run方法创建任务,而不是使用冷任务。

// don't use the cancellation token for the third task as you used for the previous ones
var task3 = Task.Factory.ContinueWhenAll(
                    new[] { task1, task2 },
                    tasks =>
                    {
                        if (tasks[0].Exception != null)
                        {
                            tasks[0].Exception.Handle(exc =>
                            {
                                Console.WriteLine("First task failed :(");
                                return false; // signal that exception was handled, so it won't propagate
                            });
                            // add additional code here, or inside the Handle method above
                        }

                        if (tasks[1].Exception != null)
                        {
                            tasks[1].Exception.Handle(exc =>
                            {
                                Console.WriteLine("Second task failed :(");
                                return false; // signal that exception was handled, so it won't propagate
                            });
                            // add additional code here, or inside the Handle method above
                        }

                        // do the same for the rest of the tasks or iterate throught them with a foreach loop...
                    });
 类似资料:
  • 问题内容: 我已经为两个窗口/阶段编写了一个控制器。在MainClass中打开第一个窗口。如果用户单击按钮,则控制器中的第二个按钮。如何在applyFor()方法中从second.fxml获取TextFields? 谢谢。 问题答案: 在fxml之间共享控制器不是很好,除非它们具有相同的用途。在这里,这两个fxml似乎有不同的用途(帐户管理,登录或其中一个类似,并为另一个创建新帐户)。更糟糕的是,

  • 我在Eclipse中获得了一个Hashmap条目,如下所示: 链接到hashmap输出的图片 我无法使用键=“value”获取值。我收到的错误是:java。lang.ClassCastException:类java。无法将lang.Double转换为java类。util。Map(java.lang.Double和java.util.Map位于加载程序“bootstrap”的模块java.base中

  • 我不清楚如何在RXJava中实现任务取消。 我对移植使用Guava的ListenableFuture构建的现有API很感兴趣。我的用例如下: 我有一个单独的操作,它由一系列由未来连接的未来组成。transform() RxJava wiki中关于这一点的信息很少;我能找到的唯一取消参考提到等效于. NET的,但据我所知,订阅仅提供取消订阅序列中后续值的能力。 我不清楚如何通过这个API实现“任何订

  • 我是从我的应用程序连接到互联网的小新,所以我得到了这个错误,我的代码在这里。 UyariPencerem 和kulaniciKontrol 和 islemTamam 代码 感谢您的帮助...

  • 如何从容器内部获取docker的容器名称? 我不能使用“inspect”,因为我必须使用容器内部的脚本从JSON url获取信息。

  • 我们已经在 无阻塞调用 一节中看到了取消任务的示例。 在这节,我们将回顾一下,在一些更加详细的情况下取消的语义。 一旦任务被 fork,可以使用 yield cancel(task) 来中止任务执行。取消正在运行的任务,将抛出 SagaCancellationException 错误。 来看看它是如何工作的,让我们先考虑一个简单的例子:一个可通过某些 UI 命令启动或停止的后台同步任务。 在接收到