异步基于委托实现和同步方法对立,异步执行时系统会开辟一个新的线程用于处理异步执行的方法函数,同时主线程继续执行,待到异步方法执行完成之后再执行回调函数。
异步方法的声明,调用:
1 /// <summary> 2 /// 一个比较耗时耗资源的私有方法,子线程进行调用 3 /// </summary> 4 /// <param name="name"></param> 5 private void DoSomethingLong(string name) 6 { 7 Console.WriteLine($"****************DoSomethingLong Start {Thread.CurrentThread.ManagedThreadId}***************"); 8 long lResult = 0; 9 for (int i = 0; i < 10000000; i++) 10 { 11 lResult += i; 12 } 13 Thread.Sleep(2000); 14 15 Console.WriteLine($"****************DoSomethingLong End {Thread.CurrentThread.ManagedThreadId}***************"); 16 }
声明委托:
1 Action<string> act = this.DoSomethingLong; 2 AsyncCallback callBack = t => { //子线程执行 3 Console.WriteLine("主线程方法执行状态"+t.IsCompleted); 4 Console.WriteLine("异步传递的值为:"+t.AsyncState); 5 }; 6 IAsyncResult iasyncResult = act.BeginInvoke("btnAsync_click", callBack, "AA"); 7 while (!iasyncResult.IsCompleted) { 8 Console.WriteLine("请等待主方法执行完毕。。。,当前线程为"+ Thread.CurrentThread.ManagedThreadId); 9 Thread.Sleep(100);//当前主线程循环等待80ms 10 }
IsCompleted字段标识异步函数是否执行完毕,用while循环判断该字段查看执行进度。
类似的方法还有:iAsyncResult.AsyncWaitHandle.WaitOne();让运行的主线程等待,默认不填主线程一直等到子线程执行完毕。 WaitOne()方法中可以传递用户要等待的毫秒数,如果达到了用户填写的毫秒数,异步程序还没有执行完,那么主线程就不再等待接着执行下面的代码。
带有返回值的异步调用:
1 Func<string, int> func = t => 2 { 3 Thread.Sleep(2000); 4 return DateTime.Now.Year; 5 }; 6 7 IAsyncResult iAsyncResult = func.BeginInvoke("消逝青春", t => 8 { 9 int iResult = func.EndInvoke(t); //异步方法执行完毕,在会回调中获取异步方法返回的值 10 Console.WriteLine("异步方法计算后返回的值为:"+iResult); 11 }, null);
EndInvoke函数的使用。