C# 中提供多線程同步退出機制,詳參對象: CancellationTokenSource
CancellationTokenSource 中暫未提供復位操作,因此當調用Cancle 之后,若再次調用,需重新初使化對象。
代碼示例:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace CancellationTokenSourceTest { class Program { static void Main(string[] args) { //一種多線程取消任務開關對象 CancellationTokenSource s1 = new CancellationTokenSource(); CancellationTokenSource s2 = new CancellationTokenSource(); //s1 , 或者 s2 取消,導致 s3 取消 CancellationTokenSource s3 = CancellationTokenSource.CreateLinkedTokenSource(s1.Token, s2.Token); //異步執行結束 回調 s1.Token.Register(new Action(() => { Console.WriteLine("線程{0} 執行回調!", System.Threading.Thread.CurrentThread.ManagedThreadId); })); s2.Token.Register(new Action(() => { Console.WriteLine("線程{0} 執行回調!", System.Threading.Thread.CurrentThread.ManagedThreadId); })); s3.Token.Register(new Action(() => { Console.WriteLine("線程{0} 執行回調!", System.Threading.Thread.CurrentThread.ManagedThreadId); })); //異步執行 ThreadPool.QueueUserWorkItem(new WaitCallback(Print), s1.Token); //Token 中包含回調信息,執行結束 觸發 Register 關聯方法。 // System.Threading.Thread.Sleep(2000); ThreadPool.QueueUserWorkItem(new WaitCallback(Print), s2.Token); // System.Threading.Thread.Sleep(2000); ThreadPool.QueueUserWorkItem(new WaitCallback(Print), s3.Token); Console.WriteLine(); s2.CancelAfter(3000); //若各線程傳遞各自tocken ,執行回調線程: s2 , s3 //s1.CancelAfter(3000); //若各線程傳遞各自tocken ,執行回調線程: s1 , s3 //s3.Cancel(); //若各線程傳遞各自tocken ,只觸發 s3 , 不會觸發 s1 , s2 回調。 //注意: 若各線程傳遞s3.token , s1 , s2 任意Cancle , s1 , s2 , s3 均會回調。 Console.ReadKey(); } static void Print(object objToken) { CancellationToken token = (CancellationToken)objToken; Console.WriteLine("Print , 開始等待{0}...", System.Threading.Thread.CurrentThread.ManagedThreadId); if (token.WaitHandle.WaitOne()) { Console.WriteLine( "直到 調用 Cancel() 執行此處 "); } //while (!token.IsCancellationRequested) { // //調用Cancel() 后 退出循環 //} Console.WriteLine("執行退出 {0}!" , System.Threading.Thread.CurrentThread.ManagedThreadId); } } }