C#基于任务的异步模式
using System; using System.Threading; using System.Threading.Tasks; using static System.Console; //异步编程 //1.异步模式 //2.基于事件的异步模式 //3.基于任务的异步模式 namespace ConsoleApp { class Program { public static void TaskMethod(object o) { Log(o?.ToString()); } private static object s_logLock = new object(); public static void Log(string title) { lock (s_logLock) { WriteLine(title); WriteLine($"TaskID:{Task.CurrentId?.ToString() ?? "no task"}, " + $"thread:{Thread.CurrentThread.ManagedThreadId}"); WriteLine($"is background thread: {Thread.CurrentThread.IsBackground}"); WriteLine(); } } static void Main(string[] args) { //StartNew和Run会立即启动 //方法1 var tf = new TaskFactory(); Task t1 = tf.StartNew(TaskMethod, "using a task factory"); //方法2 Task t2 = Task.Factory.StartNew(TaskMethod, "factory via task"); //方法3 var t3 = new Task(TaskMethod, "using a task constructor and Start"); t3.Start(); //方法4 Task t4 = Task.Run(() => TaskMethod("using the Run method")); t1.Wait(); t2.Wait(); t3.Wait(); t4.Wait(); //主线程没有任务ID,也不是线程池中的线程 TaskMethod("main thread"); var t5 = new Task(TaskMethod, "run sync"); //会使用相同的线程作为主调线程 t5.RunSynchronously(); //如果任务的代码长时间运行,就应该使用TaskCreationOptions.LongRunning //即告诉任务调度器创建一个新的线程,而不使用线程池中的线程 var t6 = new Task(TaskMethod, "long running", TaskCreationOptions.LongRunning); t6.Start(); //任务结果 future //使用泛型Task<TResult> var t7 = new Task<Tuple<int, int>>(TaskWithResult, Tuple.Create(8, 3)); t7.Start(); WriteLine(t7.Result); t7.Wait(); WriteLine($"result from task: {t7.Result.Item1} {t7.Result.Item2}"); //连续的任务 //一个要使用前一个任务的结果,如果前一个失败了,这个任务就应该执行一些清理工作 //无论前一个任务是如何结束的,后面的任务都会接着启动 Task t8 = new Task(DoOnFirst); Task t9 = t8.ContinueWith(DoOnSecond); Task t10 = t8.ContinueWith(DoOnSecond); Task t11 = t9.ContinueWith(DoOnSecond); t8.Start(); //出错时启动 Task t12 = t8.ContinueWith(DoOnSecond, TaskContinuationOptions.OnlyOnFaulted); Task.WaitAll(t8, t9, t10, t11); //任务取消 CancelTask(); ReadKey(); } public static Tuple<int, int> TaskWithResult(object divsion) { if (divsion is Tuple<int, int>) { Tuple<int, int> div = (Tuple<int, int>)divsion; int result = div.Item1 / div.Item2; int reminder = div.Item1 % div.Item2; WriteLine("task creates a result..."); return Tuple.Create(result, reminder); } return null; } private static void DoOnFirst() { WriteLine($"doing some task {Task.CurrentId}"); Task.Delay(1000).Wait(); } private static void DoOnSecond(Task t) { WriteLine($"task {t.Id} finished"); WriteLine($"this task id {Task.CurrentId}"); WriteLine("do some cleanup"); Task.Delay(1000).Wait(); } public static void CancelTask() { var cts = new CancellationTokenSource(); //注册一个将在取消此CancellationToken时调用的委托。 cts.Token.Register(() => WriteLine("*** task canceled")); //在指定的毫秒数后计划对此CancellationTokenSource 的取消操作。 cts.CancelAfter(500); //cts.Cancel();//立即取消 Task t1 = Task.Run(() => { WriteLine("in task"); while (true) { Task.Delay(100).Wait(); CancellationToken token = cts.Token; if (token.IsCancellationRequested) { WriteLine("canceling was requested, " + "canceling from within the task"); token.ThrowIfCancellationRequested(); break; } WriteLine("in loop"); Task.Yield(); } WriteLine("task finished without cancellation"); }, cts.Token); try { t1.Wait(); } catch(AggregateException ex) { WriteLine($"exception: {ex.GetType().Name}, {ex.Message}"); foreach(var innerException in ex.InnerExceptions) { WriteLine($"inner exception: {ex.InnerException.GetType()}," + $"{ex.InnerException.Message}"); } } } } }