• 【C#】线程协作式取消


    Microsoft .Net Framework 提供了一个标准的取消操作的模式。这个模式是协作式的,意味着你想取消的操作必须显示地支持取消。

    CLR为我们提供了两个类:

      System.Threading.CancellationTokenSource

      System.Threading.CancellationToken

    CancellationToken实例是一个轻量级的值类型,因为它包含单个私有字段:CancellationTokenSource的一个引用。在一个计算限制操作的循环中,可以定时调用CancellationToken的IsCancellationRequested属性,了解循环是否应该提前终止,进而终止计算机限制的操作。

       我附上我常用代码:

    CancellationTokenSource cancel=new CancellationTokenSource();
    
        Task.Factory.StartNew(() =>
            {
                while (!cancel.IsCancellationRequested)
                {
                     //do something
                }
            }, cancel.Token);// cancel.Token->CancellationToken
      
         //取消操作
         cancel.Cancel();
         cancel.Dispose();
         cancel=null; 

    如果用到线程池,也可以使用这个类

      public void main()
      {
             var cancel=new CancellationTokenSource();
             ThreadPool.QueueUserWorkItem(_ =>
                {
                    while (!cancel.IsCancellationRequested)
                    {
                        //do something
                    }
                });
    
                Thread.Sleep(10 * 1000);//为了让循环多做些时间
                cancel.Cancel();
                cancel.Dispose();
      }

    这个类还有一个很好的地方,可以在自定义回调函数,在调用Cancel方法的时候使用。这个我们需要用到CancellationToken里面的Register方法(也就是new CancellationTokenSource().Token.Register(()=>{})),并且可以给一个Token多次注册,按照倒序执行。

     var cancel = new CancellationTokenSource();
                cancel.Token.Register(() =>
                {
                    MessageBox.Show("Register3");
                });
                cancel.Token.Register(() =>
                {
                    MessageBox.Show("Register");
                });
                cancel.Token.Register(() =>
                {
                    MessageBox.Show("Register1");
                });
                cancel.Token.Register(() =>
                {
                    MessageBox.Show("Register2");
                });

     弹出顺序:Register2Register1,Register,Register3

    如果想注销注册的回调函数,需要用到CancellationTokenRegistration(这个在调用Register的时候就会返回),附代码:

            CancellationTokenRegistration registration = cancel.Token.Register(() =>
                 {
                     MessageBox.Show("Register2");
                 });
                registration.Dispose();//这里可以取消    

    取消以后再跑,就只会弹出另外三个,还是倒序。

    最后,可通过链接另一组CancellationTokenSource来新建一个CancellationTokenSource对象,任何链接的CancellationTokenSource被取消,这个新的CancellationTokenSource对象就会自动被取消,附代码:

      public static void Go()
            {
                var cts1 = new CancellationTokenSource();
                cts1.Token.Register(() => Console.WriteLine("cts1 canceled"));
    
                var cts2 = new CancellationTokenSource();
                cts2.Token.Register(() => Console.WriteLine("cts2 canceled"));
    
                var linkedcts = CancellationTokenSource.CreateLinkedTokenSource(cts1.Token, cts2.Token);
                linkedcts.Token.Register(() => Console.WriteLine("linkedcts canceled"));
    
                cts2.Cancel();
    
                Console.WriteLine("cts1:{0}  cts2:{1}  linkedcts:{2}",
                    cts1.IsCancellationRequested, cts2.IsCancellationRequested, linkedcts.IsCancellationRequested);
            }

    由于cts2对象被取消了,所以linkedcts自动被取消,这里CancellationTokenSource.CreateLinkedTokenSource 有一个重载是params CancellationToken[], 理论上说,无论加多少个CancellationToken对象都是可以的。

  • 相关阅读:
    excelhelp
    导入数据到GridView
    sql2005悠改sa
    状态存储管理 encode,decode,transfer
    Session持久化
    Microsoft SQL Server 2005 数据类型
    Cookie (HttpCookie的实例)
    role设计
    ajax
    poj 3370 Halloween treats 夜
  • 原文地址:https://www.cnblogs.com/guochenkai/p/3977358.html
Copyright © 2020-2023  润新知