当我调用ThrowIfCancellationRequested()时,用户代码未对OperationCanceledException进行处理

时间:2014-02-19 08:17:11

标签: c# .net c#-4.0

当我试图在调试模式中取消猴子的遗传世代时,我从“用于.NET Framework并行编程的样本”MSDN获得以下代码我得到'OperationCanceledException未被用户代码处理'在线token.ThrowIfCancellationRequested();。我添加了最后的异常处理'UnobservedTaskException',但代码永远不会到达那里。请帮我解决这个问题:

  public MainForm()
    {
        InitializeComponent();

        txtTarget.Text = _targetText;
        _uiTasks = new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());
        TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
    }

    void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
    {
        e.SetObserved();
    }

  private int _currentIteration;
    private CancellationTokenSource _cancellation;

    private void btnRun_Click(object sender, EventArgs e)
    {
        if (_cancellation == null)
        {
            _cancellation = new CancellationTokenSource();
            GeneticAlgorithmSettings settings = new GeneticAlgorithmSettings { PopulationSize = Int32.Parse(txtMonkeysPerGeneration.Text) };

            txtBestMatch.BackColor = SystemColors.Window;
            lblGenerations.BackColor = SystemColors.Control;
            lblGenPerSec.Text = lblGenerations.Text = "-";
            lblElapsedTime.Text = "0";
            btnRun.Text = "Cancel";
            chkParallel.Visible = false;

            _startTime = _lastTime = DateTimeOffset.Now;
            timerElapsedTime.Start();

            // Run the work in the background
            _cancellation = new CancellationTokenSource();
            var token = _cancellation.Token;
            bool runParallel = chkParallel.Checked;
            Task.Factory.StartNew(() =>
            {
                // Create the new genetic algorithm
                var ga = new TextMatchGeneticAlgorithm(runParallel, _targetText, settings);
                TextMatchGenome? bestGenome = null;
                                       // Iterate until a solution is found or until cancellation is requested
                    for (_currentIteration = 1; ; _currentIteration++)
                    {
                        token.ThrowIfCancellationRequested();

                        // Move to the next generation
                        ga.MoveNext();

                        // If we've found the best solution thus far, update the UI
                        if (bestGenome == null ||
                            ga.CurrentBest.Fitness < bestGenome.Value.Fitness)
                        {
                            bestGenome = ga.CurrentBest;
                            _uiTasks.StartNew(() => txtBestMatch.Text = bestGenome.Value.Text);

                            // If we've found the solution, bail.
                            if (bestGenome.Value.Text == _targetText) break;
                        }
                    }                    
                // When the task completes, update the UI
            }, token).ContinueWith(t =>
            {
                timerElapsedTime.Stop();
                chkParallel.Visible = true;
                btnRun.Text = "Start";
                _cancellation = null;
                switch (t.Status)
                {
                    case TaskStatus.Faulted:
                        MessageBox.Show(this, t.Exception.ToString(), "Error");
                        break;
                    case TaskStatus.RanToCompletion:
                        txtBestMatch.BackColor = Color.LightGreen;
                        lblGenerations.BackColor = Color.LemonChiffon;
                        break;
                }                    
            }, _uiTasks.Scheduler);
        }
        else _cancellation.Cancel();
    }

3 个答案:

答案 0 :(得分:3)

您可能已将Visual Studio设置为停止所有抛出的异常。你可以忽略这个(点击继续)或禁用这个选项:Debug菜单&gt;例外。清除“Common Language Runtime Exceptions”抛出列的复选框。或者,您可以取消选中特定的例外(单击“查找”按钮并搜索OperationCanceledException)。

答案 1 :(得分:2)

在4.5上玩任务并获得相同的错误,但原因不同。

在此发布,因为这是最热门的搜索结果,我花了一段时间才找到原因。

try
{
    await Task.Run(() => DoWork());
    label1.Text = "Finished.";
}
catch (OperationCanceledException)
{
    label1.Text = "Cancelled.";
}

哪个跑了:

private async void DoWork()
{
    // WORK STUFF
    {
        workerCancel.Token.ThrowIfCancellationRequested();
    }
}

取消会导致未处理的错误,因为我把void而不是Task:

private async Task DoWork()

答案 2 :(得分:1)

实际处理了异常......确保只按F5查看已被捕获。要将调试器设置为不捕获用户未处理的异常,请按Ctrl + Alt + E并取消选择User-unhandled