国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

【C#】線程協作式取消

2019-11-17 02:53:11
字體:
來源:轉載
供稿:網友

【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");            });

彈出順序:Register2,Register1,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對象都是可以的。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 盐边县| 随州市| 通榆县| 裕民县| 宁津县| 永康市| 延津县| 玉溪市| 芷江| 彭州市| 鄂温| 基隆市| 卓资县| 依安县| 健康| 富川| 祁阳县| 盐城市| 临沭县| 遵化市| 宁津县| 道孚县| 朝阳县| 临武县| 汽车| 新晃| 措美县| 西青区| 佛学| 民和| 定边县| 托克逊县| 林周县| 海原县| 台中市| 修武县| 思茅市| 搜索| 滦平县| 聊城市| 潮安县|