C#异步编程基础
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace AsyncBasic { class OperateClass { #region 异步编程—创建任务 /// <summary> /// 创建同步方法 /// </summary> /// <param name="name"></param> /// <returns></returns> public static string Greeting(string name) { Thread.Sleep(3000); return string.Format("Hello,{0}",name); } /// <summary> /// 异步方法 /// </summary> /// <param name="name"></param> /// <returns></returns> public static Task<string> GreetingAsync(string name) { return Task.Run<string>(()=> { return Greeting(name); }); } #endregion #region 异步编程—调用异步方法 /// <summary> /// 调用异步方法 ///使用await关键字需要有用async修饰符声明的方法 /// </summary> public async static void CallerWithAsync() { string result = await GreetingAsync("异步方法调用测试"); Console.WriteLine(result); //以上等价于 Console.WriteLine(await GreetingAsync("输出方式二【异步方法调用测试】")); } #endregion #region 异步编程—延续任务 /// <summary> /// 延续任务 /// </summary> public static void CallerWithContinuationTask() { Task<string> t1 = GreetingAsync("延续任务"); t1.ContinueWith(t => { string result = t.Result; Console.WriteLine(result); }); } #endregion #region 异步编程—使用多个异步方法 /// <summary> /// 按顺序调用异步编程的方法 /// </summary> public async static void MultipleAsyncMethods() { string s1 = await GreetingAsync("顺序1"); string s2 = await GreetingAsync("顺序2"); Console.WriteLine("两个方法的完成顺序"); Console.WriteLine("Result 1:{0} Result 2:{1}",s1,s2); } /// <summary> /// 使用组合器 /// 异步方法不依赖于其他其他异步方法,每个异步方法都不使用await /// 返回Task<string> /// </summary> public async static void MultipleAsyncMethodsWithCombinators1() { Task<string> t1 = GreetingAsync("组合器"); Task<string> t2 = GreetingAsync("组合器1"); await Task.WhenAll(t1,t2); // Console.WriteLine("两个方法的完成顺序: Result 1:{0} Result 2:{1}", t1.Result, t2.Result); } /// <summary> /// 使用组合器 /// 异步方法不依赖于其他其他异步方法,每个异步方法都不使用await /// 返回数组 /// </summary> public async static void MultipleAsyncMethodsWithCombinators1() { Task<string> t1 = GreetingAsync("组合器"); Task<string> t2 = GreetingAsync("组合器1"); string[] result = await Task.WhenAll(t1, t2); // Console.WriteLine("两个方法的完成顺序: Result 1:{0} Result 2:{1}", result[0], result[1]); } #endregion #region 异步编程—转换异步模式 //在没有提供基于任务的异步编程模式下,使用BegainXXX和EndXXX转换异步模式 /// <summary> /// 声明同步的一个委托 /// </summary> private static Func<string, string> greetingInvoker = Greeting; //接受三个参数,返回IAsyncResult public static IAsyncResult BeginGreeting(string name, AsyncCallback callback, object state) { return greetingInvoker.BeginInvoke(name,callback,state); } // public static string EndGreeting(IAsyncResult ar) { return greetingInvoker.EndInvoke(ar); } // public static async void ConvertingAsyncPattern() { string s = await Task<string>.Factory.FromAsync<string>(BeginGreeting, EndGreeting, "转换模式", null); Console.WriteLine(s); } #endregion #region 异步编程—错误处理 /// <summary> /// 延迟后抛出一个异常 /// </summary> /// <param name="ms"></param> /// <param name="message"></param> /// <returns></returns> public static async Task ThrowAfter(int ms, string message) { await Task.Delay(ms); throw new Exception(message); } /// <summary> /// 异步方法的异常处理(2s后抛出异常) /// </summary> public static async void HandleOneError() { try { await ThrowAfter(2000, "first"); } catch(Exception ex) { Console.WriteLine("handled {0}", ex.Message); } } /// <summary> /// 多个异步方法的异常处理 /// 第二个异常不被抛出,抛出第一个异常开始处理 /// </summary> public static async void StartTwoTasks() { try { await ThrowAfter(2000, "first"); await ThrowAfter(1000, "second"); } catch (Exception ex) { Console.WriteLine("handled {0}", ex.Message); } } /// <summary> /// 多个异步方法的异常处理 /// 获取多个异常后再处理(只能看见第一个任务的异常) /// </summary> public static async void StartTwoTasksParallel() { try { Task t1 = ThrowAfter(2000, "first"); Task t2 = ThrowAfter(1000, "second"); await Task.WhenAll(t1, t2); } catch (Exception ex) { Console.WriteLine("handled {0}",ex.Message); } } /// <summary> /// 多个异步方法的异常处理 /// 获取多个异常后再处理(遍历所有异常) /// </summary> public static async void ShowAggregateException() { Task taskResult = null; try { Task t1 = ThrowAfter(2000, "first"); Task t2 = ThrowAfter(1000, "second"); await (taskResult = Task.WhenAll(t1, t2)); } catch (Exception ex) { Console.WriteLine("handled {0}",ex.Message); foreach (var ex1 in taskResult.Exception.InnerExceptions) { Console.WriteLine("inner exception {0}",ex1.Message); } } } #endregion #region 异步编程—取消任务 //.NET 4.0开始提供了一种标准的机制,基于任务的异步模式 /// <summary> /// 取消任务 /// </summary> public partial class MainWindow : Window { private object lockList = new object(); private CancellationTokenSource cts; /// <summary> /// 开始取消任务 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void onCancel(object sender, RoutedEventArgs e) { if (cts != null) { cts.Cancel(); } } //2.使用框架取消任务 //框架中的某些异步方法通过提供可以传入的CancellationToken的重载来支持取消任务 //3.取消自定义的任务 private async void CanelCustomTask() { await Task.Run(() => { cts.Token.ThrowIfCancellationRequested(); },cts.Token); } } #endregion } }