C# 为什么如果我尝试使用CancellationToken.Cancel()停止一个任务,那么实际的任务会在task.Wait()上被阻塞?
我正试图在C#中实现一个任务取消,下面是我的MSDN提供的示例。 我有一个Windows窗体应用程序,其中有一个图形显示来自外部设备的数据,还有一个启动/停止按钮。这是按钮内部的代码,或多或少:C# 为什么如果我尝试使用CancellationToken.Cancel()停止一个任务,那么实际的任务会在task.Wait()上被阻塞?,c#,task,cancellationtokensource,C#,Task,Cancellationtokensource,我正试图在C#中实现一个任务取消,下面是我的MSDN提供的示例。 我有一个Windows窗体应用程序,其中有一个图形显示来自外部设备的数据,还有一个启动/停止按钮。这是按钮内部的代码,或多或少: if (drawGraph_task == null) { cts = new System.Threading.CancellationTokenSource(); token = cts.Token; drawGraph_task = new Task(() =>
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(),但有时我也有同样的效果,有时我的catch无法捕获异常。我做错了什么?
为了完整性,x和y的计算包括:
- MathNet插值库
- 调用内部生成的库进行特定于协议的通信,以等待事件(它总是启动的,因此这不是问题的根源)
代码>语句?可能任务在调用外部方法时遇到问题……您正在调用drawGraph_task.Wait()代码>,大概在UI线程上。同时,您的独立任务正在尝试做的大量工作是通过调用
尝试返回UI线程。除非你非常幸运,否则你不太可能在正确的时候调用Cancel
,这样你的工作人员就要查询令牌了。基本上,如果你手动创建任务
,然后不得不编写大量基于调用
的代码,你可能采取了错误的方法来分割你的工作。在这里,任务中的每一行代码,除了取消位,实际上都需要在UI线程上运行。单独运行的好处是什么?等待是阻塞,您试图从哪里调用。取消,在代码中看不到它。@tigerswithguitars-取消被称为等待上方的4行。