如何使用的CancellationToken属性? [英] How to use the CancellationToken property?

查看:372
本文介绍了如何使用的CancellationToken属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

相较于preceding code 类RulyCanceler ,我想跑使用code CancellationTokenSource

我如何使用它作为取消标记,即没有抛出/捕获异常提及?我可以使用 IsCancellationRequested 属性?

我试图用这样的:

  cancelToken.ThrowIfCancellationRequested();

 尝试
{
  新的Thread(()=>工作(cancelSource.Token))。开始();
}
赶上(OperationCanceledException)
{
  Console.WriteLine(取消了!);
}

但是这给了上运行时错误cancelToken.ThrowIfCancellationRequested(); 中的方法工作(的CancellationToken cancelToken)

  System.OperationCanceledException了未处理
  消息=操作被取消。
  来源= mscorlib程序
  堆栈跟踪:
       在System.Threading.CancellationToken.ThrowIfCancellationRequested()
       在_7CancellationTokens.Token.Work(的CancellationToken cancelToken)在C:\\ XXX \\ Token.cs:33行
       在_7CancellationTokens.Token<> c__DisplayClass1&l​​t;主>在Çb__0():\\ XXX \\ Token.cs:行22
       在System.Threading.ThreadHelper.ThreadStart_Context(对象状态)
       在System.Threading.ExecutionContext.Run(ExecutionContext中的ExecutionContext,ContextCallback回调,对象状态,布尔ignoreSyncCtx)
       在System.Threading.ExecutionContext.Run(ExecutionContext中的ExecutionContext,ContextCallback回调,对象状态)
       在System.Threading.ThreadHelper.ThreadStart()
  的InnerException:

在code,我成功运行抓住了OperationCanceledException在新线程:

 使用系统;
使用的System.Threading;
命名空间_7CancellationTokens
{
  内部类令牌
  {
    私有静态无效的主要()
    {
      VAR cancelSource =新CancellationTokenSource();
      新的Thread(()=>
      {
         尝试
         {
           工作(cancelSource.Token); //)。开始();
         }
         赶上(OperationCanceledException)
         {
            Console.WriteLine(取消了!);
         }
         })。开始();      Thread.sleep代码(1000);
      cancelSource.Cancel(); //安全取消的工人。
      到Console.ReadLine();
    }
    私有静态无效的工作(的CancellationToken cancelToken)
    {
      而(真)
      {
        Console.Write(345);
        cancelToken.ThrowIfCancellationRequested();
      }
    }
  }
}


解决方案

您可以实现您的工作方式如下:

 私有静态无效的工作(的CancellationToken cancelToken)
{
    而(真)
    {
        如果(cancelToken.IsCancellationRequested)
        {
            返回;
        }
        Console.Write(345);
    }
}

就是这样。你总是需要自己处理取消 - 从方法退出时,它是适当的时候退出(让您的工作和数据是一致的状态)

更新:我preFER不写而(!cancelToken.IsCancellationRequested)因为经常有少量出口点在那里你可以停止整个循环体和循环执行安全通常有一定的逻辑条件退出(遍历集合中的所有等项目)。所以,我认为这是最好不要混了,因为他们的条件有不同的打算。

Compared to the preceding code for class RulyCanceler, I wanted to run code using CancellationTokenSource.

How do I use it as mentioned in Cancellation Tokens, i.e. without throwing/catching an exception? Can I use the IsCancellationRequested property?

I attempted to use it like this:

cancelToken.ThrowIfCancellationRequested();

and

try
{
  new Thread(() => Work(cancelSource.Token)).Start();
}
catch (OperationCanceledException)
{
  Console.WriteLine("Canceled!");
}

but this gave a run-time error on cancelToken.ThrowIfCancellationRequested(); in method Work(CancellationToken cancelToken):

System.OperationCanceledException was unhandled
  Message=The operation was canceled.
  Source=mscorlib
  StackTrace:
       at System.Threading.CancellationToken.ThrowIfCancellationRequested()
       at _7CancellationTokens.Token.Work(CancellationToken cancelToken) in C:\xxx\Token.cs:line 33
       at _7CancellationTokens.Token.<>c__DisplayClass1.<Main>b__0() in C:\xxx\Token.cs:line 22
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:

The code that I successfully ran caught the OperationCanceledException in the new thread:

using System;
using System.Threading;
namespace _7CancellationTokens
{
  internal class Token
  {
    private static void Main()
    {
      var cancelSource = new CancellationTokenSource();
      new Thread(() =>
      {
         try
         {
           Work(cancelSource.Token); //).Start();
         }
         catch (OperationCanceledException)
         {
            Console.WriteLine("Canceled!");
         }
         }).Start();

      Thread.Sleep(1000);
      cancelSource.Cancel(); // Safely cancel worker.
      Console.ReadLine();
    }
    private static void Work(CancellationToken cancelToken)
    {
      while (true)
      {
        Console.Write("345");
        cancelToken.ThrowIfCancellationRequested();
      }
    }
  }
}

解决方案

You can implement your work method as follows:

private static void Work(CancellationToken cancelToken)
{
    while (true)
    {
        if(cancelToken.IsCancellationRequested)
        {
            return;
        }
        Console.Write("345");
    }
}

That's it. You always need to handle cancellation by yourself - exit from method when it is appropriate time to exit (so that your work and data is in consistent state)

UPDATE: I prefer not writing while (!cancelToken.IsCancellationRequested) because often there are few exit points where you can stop executing safely across loop body, and loop usually have some logical condition to exit (iterate over all items in collection etc.). So I believe it's better not to mix that conditions as they have different intention.

这篇关于如何使用的CancellationToken属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆