![](/img/trans.png)
[英]CancellationTokenSource does not cancel task after given timeout
[英]CancellationTokenSource does not cancel the task
对于一个启动任务而另一个停止该任务的场景,我有两个按钮。
// this is the property which is used to cancel the task
CancellationTokenSource cTokenSource;
private async void OnReadCommand()
{
cTokenSource = new CancellationTokenSource();
ReadAction();
}
private async void ReadAction()
{
Task.Factory.StartNew(() => {
while (true)
{
Task.Delay(TimeSpan.FromSeconds(2)).Wait();
//writing in debug console
Debug.WriteLine($"Some Random Nos : {Guid.NewGuid().ToString()}");
//sending it to the ui for testing
uiContext.Send(x => MessageArea2Content.Message = Guid.NewGuid().ToString(), null);
}
},cTokenSource.Token);
}
private async void OnCancelCommand()
{
// it's used to cancel the task
cTokenSource.Cancel();
}
我的应用程序是 wpf 并使用 mvvm 模式和棱镜库。 在调用 OnCancelCommand 时,任务在后台运行并打印 GUID。 我必须仅在 OnCancelCommand 上取消任务。
您需要自己实现退出循环的代码:
private async void ReadAction()
{
Task.Factory.StartNew(() => {
while (true)
{
Task.Delay(TimeSpan.FromSeconds(2)).Wait();
//writing in debug console
Debug.WriteLine($"Some Random Nos : {Guid.NewGuid().ToString()}");
//sending it to the ui for testing
uiContext.Send(x => MessageArea2Content.Message = Guid.NewGuid().ToString(), null);
cTokenSource.Token.ThrowIfCancellationRequested();
}
},cTokenSource.Token);
}
或者
private async void ReadAction()
{
Task.Factory.StartNew(() => {
while (true)
{
Task.Delay(TimeSpan.FromSeconds(2)).Wait();
//writing in debug console
Debug.WriteLine($"Some Random Nos : {Guid.NewGuid().ToString()}");
//sending it to the ui for testing
uiContext.Send(x => MessageArea2Content.Message = Guid.NewGuid().ToString(), null);
if (cTokenSource.Token.IsCancellationRequested)
{
break; // or return;
}
}
},cTokenSource.Token);
您可以在文档任务 Class中找到使用示例。 将 CancellationToken 传递给 StartNew 方法的唯一好处是,如果在任务开始之前取消源,它可以自动为您取消任务。 但是,要在运行期间取消它,您需要自己编写逻辑代码。 这是关于https://stackoverflow.com/questions/48312544/whats-the-benefit-of-passing-a-cancellationtoken-as-a-parameter-to-task-run#:~:text=的另一个好读物在%20summary%2C%20providing%20the%20cancellation,to%20start%20running%20the%20task 。
此外,我建议您在 StartNew 中执行的逻辑中使用 await ,这样您就不会失去异步的好处:
private async void ReadAction()
{
Task.Factory.StartNew(async () => {
while (true)
{
await Task.Delay(TimeSpan.FromSeconds(2));
//writing in debug console
Debug.WriteLine($"Some Random Nos : {Guid.NewGuid().ToString()}");
//sending it to the ui for testing
uiContext.Send(x => MessageArea2Content.Message = Guid.NewGuid().ToString(), null);
if (cTokenSource.Token.IsCancellationRequested)
{
break; // or return;
}
}
},cTokenSource.Token)
这样线程将不再被阻塞,并且将在调用延迟期间被释放。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.