为什么debug不同于没有调试运行(取消任务)?

时间:2010-08-23 02:46:04

标签: c# parallel-processing task-parallel-library

我制作了一个程序来测试C#4.0中的并行编程。但是,有一个问题,我无法弄清楚原因。

我写了一个方法

    private void compute(int startValue, int endValue, ConcurrentBag<Pair> theList)
    {
        try
        {
            Task computation = Task.Factory.StartNew(() => { findFriendlyNumbers(startValue, endValue, theList, tokenSource.Token); }, tokenSource.Token);
            Task.WaitAll(computation);
            StringBuilder builder = new StringBuilder();
            foreach (Pair p in theList)
            {
                builder.AppendLine(p.ToString());
            }

            this.textBlockResult.Dispatcher.Invoke(new Action(() =>
            {
                this.textBlockResult.Text = builder.ToString();
                this.progressBar1.Visibility = System.Windows.Visibility.Hidden;
            }));
        }
        catch (AggregateException aEx)
        {
            MessageBox.Show("Entering");  //For debug, but never runs
            aEx.Handle(handleCancelling);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

在单独的线程(UI线程除外)上运行。

功能(简化)

        private void findFriendlyNumbers(int start, int end, ConcurrentBag<Pair> list, CancellationToken token)
    {
        //some initialization and computation

        for (int i = start; i <= end; i++)
        {
            //check whether it's cancelled
            token.ThrowIfCancellationRequested();

            //some computation
        }
    }

问题是,当tokenSource被取消时,将出现错误“OperationCanceledException不由用户代码处理”,就好像catch块不存在一样。我不知道为什么,因为我的代码类似于教科书和MSDN中的代码。

谢谢。

编辑: 我不到一个月前就写了一个类似的程序,然后一切都很好。今天我试着再次运行它,同样的问题发生了。我完成程序后安装了Microsoft Visual Web Developer 2010 Express,我不确定这是否是原因。我不明白,相同的代码,不同的结果。

编辑: 我想到了这个问题,发现哪里出错了。过去,我现在使用debug时使用“run without debugging”。无需调试即可运行解决问题。如果有人告诉我为什么debug与“run without debug”不同,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

您正在将取消令牌传递给TaskFactory.StartNew方法。这使得Task特别对待它:作为取消而不是错误的指示。

如果您没有将令牌作为参数传递给TaskFactory.StartNew,那么它将被视为错误并被捕获。如果您确实将其作为参数保留,则需要使用Task.IsCanceled检查取消,而不是例外。

附注:最好不要使用Invoke来同步UI线程。 I have an example of Task objects properly doing UI progress updates on my blog.