C#的async和await
1 例子1: 2 3 public class MyClass 4 { 5 public MyClass() 6 { 7 DisplayValue(); //这里不会阻塞 8 System.Diagnostics.Debug.WriteLine("MyClass() End."); 9 } 10 public Task<double> GetValueAsync(double num1, double num2) 11 { 12 return Task.Run(() => 13 { 14 for (int i = 0; i < 1000000; i++) 15 { 16 num1 = num1 / num2; 17 } 18 return num1; 19 }); 20 } 21 public async void DisplayValue() 22 { 23 double result = await GetValueAsync(1234.5, 1.01);//此处会开新线程处理GetValueAsync任务,然后方法马上返回 24 //这之后的所有代码都会被封装成委托,在GetValueAsync任务完成时调用 25 System.Diagnostics.Debug.WriteLine("Value is : " + result); 26 } 27 } 28 29 上面在MyClass的构造函数里调用了async关键字标记的异步方法DisplayValue(),DisplayValue()方法里执行了一个await关键字标记的异步任务GetValueAsync(),这个异步任务必须是以Task或者Task<TResult>作为返回值的,而我们也看到,异步任务执行完成时实际返回的类型是void或者TResult,DisplayValue()方法里await GetValueAsync()之后的所有代码都会在异步任务完成时才会执行。 30 31 DisplayValue()方法实际执行的代码如下: 32 33 public void DisplayValue() 34 { 35 System.Runtime.CompilerServices.TaskAwaiter<double> awaiter = GetValueAsync(1234.5, 1.01).GetAwaiter(); 36 awaiter.OnCompleted(() => 37 { 38 double result = awaiter.GetResult(); 39 System.Diagnostics.Debug.WriteLine("Value is : " + result); 40 }); 41 } 42 可以看到,async和await关键字只是把上面的代码变得更简单易懂而已。 43 程序的输出如下: 44 45 MyClass() End. 46 47 Value is : 2.47032822920623E-322 48 49 普通Function执行异步调用: 50 51 public static class TaskAsyncHelper 52 { 53 /// <summary> 54 /// 将一个方法function异步运行,在执行完毕时执行回调callback 55 /// </summary> 56 /// <param name="function">异步方法,该方法没有参数,返回类型必须是void</param> 57 /// <param name="callback">异步方法执行完毕时执行的回调方法,该方法没有参数,返回类型必须是void</param> 58 public static async void RunAsync(Action function, Action callback) 59 { 60 Func<System.Threading.Tasks.Task> taskFunc = () => 61 { 62 return System.Threading.Tasks.Task.Run(() => 63 { 64 function(); 65 }); 66 }; 67 await taskFunc(); 68 if (callback != null) 69 callback(); 70 } 71 /// <summary> 72 /// 将一个方法function异步运行,在执行完毕时执行回调callback 73 /// </summary> 74 /// <typeparam name="TResult">异步方法的返回类型</typeparam> 75 /// <param name="function">异步方法,该方法没有参数,返回类型必须是TResult</param> 76 /// <param name="callback">异步方法执行完毕时执行的回调方法,该方法参数为TResult,返回类型必须是void</param> 77 public static async void RunAsync<TResult>(Func<TResult> function, Action<TResult> callback) 78 { 79 Func<System.Threading.Tasks.Task<TResult>> taskFunc = ()=> 80 { 81 return System.Threading.Tasks.Task.Run(()=> 82 { 83 return function(); 84 }); 85 }; 86 TResult rlt = await taskFunc(); 87 if(callback != null) 88 callback(rlt); 89 } 90 } 91 使用很简单,将方法名作为参数传进去就行了. 92 93 例子2: 94 95 /* 96 public Task<int> Write(byte[] data, int len) 97 { 98 return Task.Run(() => 99 { 100 byte[] ds = new byte[] { 0x58, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 08, 0x4c }; 101 if (HwPort.IsOpen) HwPort.Write(ds, 0, ds.Length); 102 return len; 103 }); 104 } 105 public async void WriteAsync(byte[] data = null, int len = 0) 106 { 107 int rt = await Write(data, len); 108 Console.WriteLine("async/await: " + rt); 109 } 110 */ 111 public async void Write(byte[] data = null, int len = 0) 112 { 113 var rt = await Task.Run(() => 114 { 115 byte[] ds = new byte[] {0x58, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 08, 0x4c}; 116 if (HwPort.IsOpen) HwPort.Write(ds, 0, ds.Length); 117 return len; 118 }); 119 Console.WriteLine("async/await completed.[" + rt + "]"); 120 }