控制异步多线程顺序的一些方式
1.异步回调,当线程结束时触发回调函数,用于线程结束时的操作(日志打印等)
Console.WriteLine(); Console.WriteLine("*********btnAsyncAdvance_Click 异步方法 start {0}********",Thread.CurrentThread.ManagedThreadId); Action<string> action = this.DoSomeThingLong; //action.Invoke("btnAsyncAdvance_Click_1"); #region 异步回调 // AsyncCallback callback = ar => // { // Console.WriteLine(ar.AsyncState); // Console.WriteLine("这波操作已经完成 {0}", Thread.CurrentThread.ManagedThreadId); // }; // action.BeginInvoke("btnAsyncAdvance_Click", callback, "april"); // #endregion
2.IsCompleted完成等待,主线程需等待异步线程执行完成再运行的情况,等待时会出现延时的问题
Console.WriteLine(); Console.WriteLine("*********btnAsyncAdvance_Click 异步方法 start {0}********",Thread.CurrentThread.ManagedThreadId); Action<string> action = this.DoSomeThingLong; //用户必须确定操作完成,才能返回----上传文件, //只有成功之后才能预览---需要等到计算任务完成才能给用户返回 //一方面文件上传,完成后才能预览;另一方面,由进度提示----只有主线程才能擦偶哦界面; // IAsyncResult asyncResult = action.BeginInvoke("文件上传", null, null); // int i = 0; // while (!asyncResult.IsCompleted) // { // if (i < 9) // { // this.ShowConsoleAndView($"当前文件上传进度为{++i * 10}%"); // } // else // { // this.ShowConsoleAndView($"当前文件上传进度为99.999%"); // } // Thread.Sleep(100); // } // // Console.WriteLine("完成文件预览,绑定到界面");
3.信号量,解决等待时的延时问题
// IAsyncResult asyncResult = action.BeginInvoke("调用接口",null,null); // Console.WriteLine("做一些别的操作,"); // Console.WriteLine("做一些别的操作,"); // Console.WriteLine("做一些别的操作,等调用接口一起做完,再往下走"); // asyncResult.AsyncWaitHandle.WaitOne(-1);//阻塞当前线程,直到收到一个信号,参数为-1表示一直等待 // //1500表示最多等待1500ms超过就超时,不继续等待 // Console.WriteLine("调用接口成功,必须是真实的成功");
4.EndInvoke,基于信号量等待,并获取返回值
#region EndInvoke //调用接口,需要返回值 Func<int> func = () => { long lResult = 0; for (int i = 0; i < 1000000000; i++) { lResult += i; } return DateTime.Now.Day; }; IAsyncResult asyncResult = func.BeginInvoke(null, null); int iResult = func.EndInvoke(asyncResult);//如果向获取异步调用的真实返回值,只能用EndInvoke Console.WriteLine(iResult); #endregion
1