c# - 如何在主应用程序线程中自动捕获 Task 对象的操作引发的异常?

标签 c# .net wpf multithreading mvvm

我注意到 DispatcherUnhandledException 事件处理程序不会捕获从主应用程序线程以外的线程抛出的异常。所以我必须像这样手动抛出它们:

Task.Factory.StartNew(() =>
{
    throw new Exception("oops! something went wrong...");

}).ContinueWith((task) =>
{
    if (task.IsFaulted)
    {
        App.Current.Dispatcher.Invoke(new Action(() =>
        {
            throw task.Exception.InnerExceptions.First();
        }));
    }
});

但是,我不想将上述 ContinueWith 方法添加到我创建的每个任务中。我宁愿有某种方法来自动处理这个问题。

最佳答案

下面的类解决了这个问题:

/// <summary>
/// Extends the System.Threading.Tasks.Task by automatically throwing the first exception to the main application thread.
/// </summary>
public class TaskEx
{
    public Task Task { get; private set; }

    private TaskEx(Action action)
    {
        Task = Task.Factory.StartNew(action).ContinueWith((task) =>
        {
            ThrowTaskException(task);
        });
    }

    public static TaskEx StartNew(Action action)
    {
        if (action == null)
        {
            throw new ArgumentNullException();
        }

        return new TaskEx(action);
    }

    public TaskEx ContinueWith(Action<Task> continuationAction)
    {
        if (continuationAction == null)
        {
            throw new ArgumentNullException();
        }

        Task = Task.ContinueWith(continuationAction).ContinueWith((task) =>
        {
            ThrowTaskException(task);
        });

        return this;
    }

    private void ThrowTaskException(Task task)
    {
        if (task.IsFaulted)
        {
            App.Current.Dispatcher.Invoke(new Action(() =>
            {
                throw task.Exception.InnerExceptions.First();
            }));
        }
    }
}

现在我可以简单地使用以下代码(与 Task 类完全相同):

TaskEx.StartNew(() =>
{
    // do something that may cause an exception
}).ContinueWith((task) =>
{
    // then do something else that may cause an exception
}).ContinueWith((task) =>
{
    // then do yet something else that may cause an exception
});

但是,与 Task 类不同的是,从这些线程之一引发的任何异常都将被我的 DispatcherUnhandledException 事件处理程序自动捕获。

关于c# - 如何在主应用程序线程中自动捕获 Task 对象的操作引发的异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12631961/

相关文章:

c# - x :FieldModifier ="Private" do and should I worry about it? 是什么

c# - 如何将列表绑定(bind)到dataGridView?

c# - 带有点网Web api的clarifai api

c# - 如何禁止因在 .NET 项目中使用 COM 引用而产生的编译器警告

c# - Autofixture.Create<int> 可以返回负值吗?

c# - 按钮内的图像和标签在单击事件 wpf 上更新

c# - GridView OnSelectedIndexChanged 事件未触发

java - 从 Web 服务响应中删除时区

c# - 使用 Entity Framework Core 将文件存储在数据库中

c# - 更改 WPF DataGrid 中单元格的背景颜色