简体   繁体   English

任务线程中抛出的异常,未被UnobservedTaskException捕获

[英]Exception thrown in Task Thread, not caught by UnobservedTaskException

I'm having trouble understanding how Exceptions are handled in TPL. 我无法理解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();
        }
    }
}

From what I understand, using the TaskScheduler.UnobservedTaskException event object is a pretty good way to help handle exceptions from tricky third-party libraries. 根据我的理解,使用TaskScheduler.UnobservedTaskException事件对象是一种帮助处理棘手的第三方库异常的好方法。 However, the Exception seems to be always thrown within the Task. 但是,异常似乎总是在Task中抛出。 It looks as if it never bubbles up to be caught by the TaskScheduler (or whatever facility handles TaskExceptions). 看起来它似乎永远不会被TaskScheduler(或任何工具处理TaskExceptions)捕获。

For code brevity, I've omitted possible try/catch locations and marked them with a comment. 为了简洁起见,我省略了可能的try / catch位置并用注释标记它们。

I'm expecting the TaskScheduler_UnobservedTaskException event handler to print to the console and observe the Exception. 我期待TaskScheduler_UnobservedTaskException事件处理程序打印到控制台并观察异常。 However, once the execution reaches the Result of the task, a WebException is thrown from within the Task. 但是,一旦执行到达任务的结果,就会从Task中抛出WebException。

Here (How to handle exceptions with TaskScheduler.UnobservedTaskException?) is the explanation. 这里(如何使用TaskScheduler.UnobservedTaskException处理异常?)是解释。 Just replace 只需更换

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

with

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

to see the message in TaskScheduler_UnobservedTaskException TaskScheduler_UnobservedTaskException查看消息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM