2
        var tokenSource2 = new CancellationTokenSource();
        CancellationToken ct = tokenSource2.Token;

        var task = Task.Factory.StartNew(() => { 
                     Thread.Sleep(4000);
                     Console.WriteLine("Done");
                     ct.ThrowIfCancellationRequested(); 
                   }, ct);

        Thread.Sleep(1000); Look here! <--- 
        tokenSource2.Cancel();

        try
        {
            Console.WriteLine("Wait");
            task.Wait();
        }
        catch (Exception e)
        {
            Console.WriteLine("Task was canceled");
        }

我不明白为什么如果我评论这一行一切正常,并且在主线程中捕获了异常,但是如果我离开这一行,异常会在子线程中抛出 ct.ThrowIfCancellationRequested(); 在这两种情况下,我们都有一个取消令牌实例。我是多线程的新手,所以我肯定会想念一些东西。

我尝试了下一个代码

    static void Main(string[] args)
    {
        Thread.CurrentThread.Name = "Main";

        Console.WriteLine("Name of the current thread is " + Thread.CurrentThread.Name);

        var tokenSource2 = new CancellationTokenSource();
        CancellationToken ct = tokenSource2.Token;
        var task = Task.Factory.StartNew(() => 
        { 
            Thread.Sleep(4000); 
            Console.WriteLine("Done");

            try
            {
                ct.ThrowIfCancellationRequested(); // If I remove the try/catch here will be unhandled exception
            }
            catch (OperationCanceledException exp)
            {
                Console.WriteLine("Task was started then canceled");   
            }

        }, ct);//ontinueWith(OnProcessImageEnded);

        Thread.Sleep(1000);
        tokenSource2.Cancel();

        try
        {
            Console.WriteLine("Wait");
            task.Wait();
        }
        catch (Exception e)
        {
            Console.WriteLine("Task was canceled");
        }

        Console.WriteLine("Task was finished");

        Console.WriteLine(task.Status);

我现在在任务的线程中处理异常,但它导致任务的状态未设置为取消。我认为这是因为现在任务无法捕获异常来处理它。什么是正确的方法?

我发现http://msdn.microsoft.com/en-us/library/ee191553.aspx这个例子也有同样的问题!如果我们在执行期间按下“c”,当我们尝试通过调用 externalToken.ThrowIfCancellationRequested(); 重新抛出时,它会抛出未处理的异常;......我很困惑。我正在使用 x64 Win 7、4.5 .net 框架

4

2 回答 2

2

当您评论该行时,我们的任务很可能在它开始之前就被取消了。因此你得到了例外。当您添加睡眠时 - 大多数情况下它将被启动,因此在您调用的任务中会发生取消ThrowIfCancellationRequested

于 2013-05-17T05:49:26.623 回答
0

我将遵从这个文档

任务.等待方法

聚合异常

任务被取消 - 或 - 在任务执行期间引发异常。如果任务被取消,则 AggregateException 在其 InnerExceptions 集合中包含一个 OperationCanceledException。

从本质上讲,这是一种比赛条件,如果您及时赶到,task.Wait您就赢了。

于 2013-05-17T05:06:05.190 回答