为什么如果我尝试使用 CancellationToken.Cancel() 停止任务,那么实际任务会卡在 Task.Wait() 上?

Why if I try to stop a task using CancellationToken.Cancel() then the actual task get stucked on Task.Wait()?

我正尝试按照我的 MSDN 提供的示例在 C# 中实现任务取消。 我有一个 Windows 表单应用程序,其中有一个图表显示来自外部设备的数据和一个 start/stop 按钮。这就是按钮内或多或少的代码:

if (drawGraph_task == null)
{
    cts = new System.Threading.CancellationTokenSource();
    token = cts.Token;
    drawGraph_task = new Task(() => 
    {
        this.Invoke(new InvokeDelegate(this.myChart.Series[0].Points.Clear));

        while (true)
        {
            // get x and y from device using external lib
            this.Invoke(new addPointXYDelegate(this.myChart.Series[0].Points.AddXY), new object[] { x, y });
            this.Invoke(new InvokeDelegate(this.chart_pressure.Update)); // update graph

            if (token.IsCancellationRequested)
            {
                return;
            }

        }
    }, token);
    this.button_main_start.Text = "Stop";
    drawGraph_task.Start();                
}
else
{
    cts.Cancel();

    try
    {
        drawGraph_task.Wait();
    }
    catch (AggregateException ae)
    {
        // do nothing
    }
    finally
    {
        cts.Dispose();
        drawGraph_task.Dispose();
        drawGraph_task = null;
        this.button_main_start.Text = "Restart";
    }
}

为什么代码仍然停留在 drawGraph_task.Wait() 调用处? 我尝试在任务中使用 token.throwIfCancellationRequested() ,但有时我有同样的效果,有时异常没有被我的捕获捕获。我究竟做错了什么? 为了完整起见,x 和 y 的计算涉及:

Task.Wait() 是同步的。如果碰巧由于 Invoke() 调用你可以 return 到这个方法,你就会陷入僵局。当您达到卡住状态时,使用调试器检查调用堆栈的状态。