为什么如果我尝试使用 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 的计算涉及:
- MathNet 插值库
- 调用内部制作的库进行协议特定通信,等待事件(它总是启动,所以这不是问题的根源)
Task.Wait() 是同步的。如果碰巧由于 Invoke() 调用你可以 return 到这个方法,你就会陷入僵局。当您达到卡住状态时,使用调试器检查调用堆栈的状态。
我正尝试按照我的 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 的计算涉及:
- MathNet 插值库
- 调用内部制作的库进行协议特定通信,等待事件(它总是启动,所以这不是问题的根源)
Task.Wait() 是同步的。如果碰巧由于 Invoke() 调用你可以 return 到这个方法,你就会陷入僵局。当您达到卡住状态时,使用调试器检查调用堆栈的状态。