Task任务取消
Task任务取消主要使用的是 CancellationTokenSource 对象下的CancellationToken 取消标记,
代码如下
using Microsoft.EntityFrameworkCore; using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace EFCOREDB { class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); #region task任务取消 TestTaskLinkedCancel(); //TestTaskSync(); //TestThreadCancel(); //TestTaskCancel(); //TestTaskCancel1(); #endregion Console.Read(); } #region Task and CancellationTokenSource /// <summary> /// 任务的链式取消 /// </summary> public async static void TestTaskLinkedCancel() { Console.WriteLine($"链接取消任务开始。。。。"); await Task.Delay(TimeSpan.FromSeconds(1)); CancellationTokenSource source1 = new CancellationTokenSource(); var token1 = source1.Token; token1.Register(() => { Console.WriteLine($"任务--1--取消回调"); }); CancellationTokenSource source2 = new CancellationTokenSource(); var token2 = source2.Token; token2.Register(() => { Console.WriteLine($"任务--2--取消回调"); }); CancellationTokenSource source3 = CancellationTokenSource.CreateLinkedTokenSource(token1, token2); var token3 = source3.Token; token3.Register(() => { Console.WriteLine($"任务--3--取消回调"); }); source1.CancelAfter(TimeSpan.FromSeconds(3)); } /// <summary> /// 同步任务和异步任务的对比 /// </summary> public static void TestTaskSync() { Console.WriteLine($"当前线程:{ Thread.CurrentThread.ManagedThreadId}"); //创建异步任务 var taskAsync = Task.Run(() => { Console.WriteLine($"异步任务:{Task.CurrentId},运行的线程:{ Thread.CurrentThread.ManagedThreadId}"); int sum = 0; Parallel.For(1, 10000, (i) => { Interlocked.Add(ref sum, i); }); return sum; }); //创建同步任务 var taskSync = new Task<long>(() => { Console.WriteLine($"同步任务:{Task.CurrentId},运行的线程:{ Thread.CurrentThread.ManagedThreadId}"); int sum2 = 0; Parallel.For(1, 10000, (i) => { Interlocked.Add(ref sum2, i); }); return sum2; }); taskSync.RunSynchronously(); Console.WriteLine($"同步任务:{taskSync.Id},运行的线程的结果:{ taskSync.Result}"); Console.WriteLine($"异步任务:{taskAsync.Id},运行的线程的结果:{ taskAsync.Result}"); } public static void TestThreadCancel() { SpinLock spinLock = new SpinLock(false); object obj = new object(); int sun1 = 0; int sun2 = 0; int sun3 = 0; //不加锁 Parallel.For(1, 10000, i => { sun1 += i; }); //不加锁 Parallel.For(1, 10000, i => { bool islock = false; try { spinLock.Enter(ref islock); sun2 += i; } finally { if (islock) { spinLock.Exit(false); } } }); //不加锁 Parallel.For(1, 10000, i => { lock (obj) { sun3 += i; } }); Console.WriteLine($"sun1={sun1}"); Console.WriteLine($"sun2={sun2}"); Console.WriteLine($"sun3={sun3}"); } /// <summary> /// 测试取消 /// </summary> public static void TestTaskThreadCancel() { #region MyRegion //var tokenSource = new CancellationTokenSource();//创建取消task实例 //var testTask = new Task(() => //{ // for (int i = 0; i < 6; i++) // { // System.Threading.Thread.Sleep(1000); // } //}, tokenSource.Token); //Console.WriteLine(testTask.Status); //testTask.Start(); //Console.WriteLine(testTask.Status); //tokenSource.Token.Register(() => //{ // Console.WriteLine("task is to cancel"); //}); //tokenSource.Cancel(); //Console.WriteLine(testTask.Status); //for (int i = 0; i < 10; i++) //{ // System.Threading.Thread.Sleep(1000); // Console.WriteLine(testTask.Status); //} #endregion CancellationTokenSource tokenSource = new CancellationTokenSource(); CancellationToken token = tokenSource.Token; try { var task = new Task(() => { for (int i = 0; i < 10; i++) { Thread.Sleep(TimeSpan.FromSeconds(1)); } }, token);//TaskCreationOptions.LongRunning token.Register(() => { Console.WriteLine($"任务取消了。。。。"); }); Console.WriteLine($"task 状态 :{task.Status}"); task.Start(); Console.WriteLine($"task 状态 :{task.Status}"); tokenSource.Cancel(); Console.WriteLine($"task 状态 :{task.Status}"); Console.WriteLine($"task是否取消看下面的 状态 "); for (int i = 0; i < 10; i++) { Thread.Sleep(TimeSpan.FromSeconds(1)); Console.WriteLine($"task 状态 :{task.Status}"); } } catch (AggregateException agg) { foreach (var item in agg.InnerExceptions) { if (item is TaskCanceledException ex) Console.WriteLine($"任务取消:{ex.Message}"); else Console.WriteLine($"任务取消:{item.GetType().Name}"); } } finally { tokenSource.Dispose(); } } /// <summary> /// 测试取消 /// </summary> public static void TestTaskCancel() { CancellationTokenSource tokenSource = new CancellationTokenSource(); CancellationToken token = tokenSource.Token; TaskFactory factory = new TaskFactory(token); List<Task<int[]>> list = new List<Task<int[]>>(); Random random = new Random(); object lockObj = new object(); for (int i = 0; i <= 10; i++) { list.Add(factory.StartNew(() => { int[] vs = new int[10]; int randomNum; for (int j = 0; j < 10; j++) { lock (lockObj) { randomNum = random.Next(0, 101); } if (randomNum == 0) { tokenSource.Cancel(); Console.WriteLine($"当前任务是:{i + 1}"); break; } vs[j] = randomNum; } return vs; }, token)); } try { var ts = factory.ContinueWhenAll(list.ToArray(), (taskList) => { long sum = 0; int accumulate = 0; foreach (var item in taskList) { foreach (var subitem in item.Result) { sum = +subitem; accumulate++; } } return sum / (double)accumulate; }, token); Console.WriteLine($"所有任务累加的结果:{ts.Result}"); } catch (AggregateException agg) { foreach (var item in agg.InnerExceptions) { if (item is TaskCanceledException ex) Console.WriteLine($"任务取消:{ex.Message}"); else Console.WriteLine($"任务取消:{item.GetType().Name}"); } } finally { tokenSource.Dispose(); } } public static void TestTaskCancel1() { // Define the cancellation token. CancellationTokenSource source = new CancellationTokenSource(); CancellationToken token = source.Token; Random rnd = new Random(); Object lockObj = new Object(); List<Task<int[]>> tasks = new List<Task<int[]>>(); TaskFactory factory = new TaskFactory(token); for (int taskCtr = 0; taskCtr <= 10; taskCtr++) { int iteration = taskCtr + 1; tasks.Add(factory.StartNew(() => { int value; int[] values = new int[10]; for (int ctr = 1; ctr <= 10; ctr++) { lock (lockObj) { value = rnd.Next(0, 101); } if (value == 0) { source.Cancel(); Console.WriteLine("Cancelling at task {0}", iteration); break; } values[ctr - 1] = value; } return values; }, token)); } try { Task<double> fTask = factory.ContinueWhenAll(tasks.ToArray(), (results) => { Console.WriteLine("Calculating overall mean..."); long sum = 0; int n = 0; foreach (var t in results) { foreach (var r in t.Result) { sum += r; n++; } } return sum / (double)n; }, token); Console.WriteLine("The mean is {0}.", fTask.Result); } catch (AggregateException ae) { foreach (Exception e in ae.InnerExceptions) { if (e is TaskCanceledException) Console.WriteLine("Unable to compute mean: {0}", ((TaskCanceledException)e).Message); else Console.WriteLine("Exception: " + e.GetType().Name); } } finally { source.Dispose(); } } #endregion } }
龙腾一族至尊龙骑