任务线程中抛出异常,未被UnobservedTaskException捕获 [英] Exception thrown in Task Thread, not caught by UnobservedTaskException

查看:184
本文介绍了任务线程中抛出异常,未被UnobservedTaskException捕获的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难理解TPL中如何处理例外情况。以下代码应该说明我的问题。

I'm having trouble understanding how Exceptions are handled in TPL. The following code should illustrate my problem.

using System;
using System.Collections.Generic;
using System.Net;
using System.Threading;
using System.Threading.Tasks;

namespace WebDLApp
{
    class Program
    {
        static void Main(string[] args)
        {
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException; // Not catching exception

            List<string> sites = new List<string>{ "http://microsoft.com", "http://yahoo.com", "http://facebook.com", "http://amazon.com", "http://foooo", "http://aol.com", "http://ask.com", "http://wikipedia.org" };
            List<Task<string>> tasks = new List<Task<string>>();


            foreach (string site in sites)
            {
                tasks.Add(Task.Factory.StartNew<string>((wsite) =>
                    {
                        using (WebClient wc = new WebClient())
                        {
                            wc.DownloadString((string)wsite); // Thrown here, always
                            return (string)wsite;
                        }
                    }, site)
                );
            }


            Task.WaitAll(tasks.ToArray()); // Can't catch here

            int counter = 1;
            foreach (var task in tasks)
            {

                Console.WriteLine(counter.ToString() + task.Result); // Can't catch here either
                counter++;
            }

            Console.ReadLine();
        }

        static void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) // Never called
        {
            Console.WriteLine(e.Exception.Message);
            e.SetObserved();
        }
    }
}

根据我的理解,使用TaskScheduler.UnobservedTaskException事件对象是一个非常好的方式来帮助处理来自棘手的第三方库的异常。但是,异常似乎总是在任务中抛出。它看起来好像从来没有被TaskScheduler(或任何设施处理TaskExceptions)捕获的气泡。

From what I understand, using the TaskScheduler.UnobservedTaskException event object is a pretty good way to help handle exceptions from tricky third-party libraries. However, the Exception seems to be always thrown within the Task. It looks as if it never bubbles up to be caught by the TaskScheduler (or whatever facility handles TaskExceptions).

为了代码简洁,我省略了可能的try / catch位置并给他们添加评论。

For code brevity, I've omitted possible try/catch locations and marked them with a comment.

我期待TaskScheduler_UnobservedTaskException事件处理程序打印到控制台并观察异常。但是,一旦执行到达任务的结果,就会从Task中抛出WebException。

I'm expecting the TaskScheduler_UnobservedTaskException event handler to print to the console and observe the Exception. However, once the execution reaches the Result of the task, a WebException is thrown from within the Task.

推荐答案

这里(如何使用TaskScheduler.UnobservedTaskException处理异常?)是解释。
只需替换

Here (How to handle exceptions with TaskScheduler.UnobservedTaskException?) is the explanation. Just replace

Task.WaitAll(tasks.ToArray()); // Can't catch here

Task.Factory.StartNew(() =>
{
    while (true)
    {
        Thread.Sleep(1000);
        GC.Collect();
    }
});
return;

中查看消息TaskScheduler_UnobservedTaskException

这篇关于任务线程中抛出异常,未被UnobservedTaskException捕获的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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