首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CancellationTokenSource不取消任务

CancellationTokenSource不取消任务
EN

Stack Overflow用户
提问于 2022-08-22 05:37:32
回答 1查看 60关注 0票数 1

我有两个按钮用于场景,其中一个启动任务,另一个停止该任务。

代码语言:javascript
复制
   // 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上取消这项任务。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-22 05:57:56

您需要自己实现退出循环的代码:

代码语言:javascript
复制
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);
}

代码语言:javascript
复制
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);

您可以在文档化任务类中找到使用示例。将CancellationToken传递给StartNew方法的唯一好处是,如果源在任务启动前被取消,它可以自动取消任务。但是,要在运行期间取消它,您需要自己编写逻辑代码。这是关于那个https://stackoverflow.com/questions/48312544/whats-the-benefit-of-passing-a-cancellationtoken-as-a-parameter-to-task-run#:~:text=In%20summary%2C%20providing%20the%20cancellation,to%20start%20running%20the%20task的另一个很好的阅读。

此外,我建议您在StartNew中执行的逻辑中使用await,这样您就不会失去异步的好处:

代码语言:javascript
复制
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)

这样,线程将不再被阻塞,并将在呼叫延迟期间释放。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73440601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档