同步和异步
同步方法
- 调用方式:代码执行一行一行的来,按照顺序执行;符合我们的开发思维;(线程ID是同一个–同一个线程来执行的所有操作);
异步方法
- 调用方式:没有等待完成,直接进入到下一行,启动一个新的线程来执行动作(线程ID不一样);
特点对比
- 不卡顿界面,UI线程(主线程)闲置,计算任务都交给子线程去执行;
- 同步方法慢,异步方法快;因为多线程并发,以资源换性能;
- 同步方法按顺序执行,异步方法无序性;
BeginInvoke详细用法
Invoke为同步调用;
BeginInvoke为异步调用;
Action<string> action = this.DoSomethingLong;
//同步
action.Invoke("btnAsync_Click");
action("btnAsync_Click");
//异步
action.BeginInvoke("btnAsync_Click", null, null); //会分配一个新的线程去执行
BeginInvoke的用法
- AsyncCallback为异步回调参数
- 如果需要往异步回调委托中传递参数,就给BeginInvoke最后一个参数传值;在异步委托的内部,可以通过AsyncState获取到参数;
Func<string,int> func = s =>
{
Console.WriteLine(s);
Thread.Sleep(5000);
//Thread.Sleep(3000);
return DateTime.Now.Year;
};
AsyncCallback callback = ar =>
{
//AsyncState获取参数
Console.WriteLine(ar.AsyncState);
//Func委托的返回值
//int iResult= func.EndInvoke(ar);
Console.WriteLine("计算成功了。。。");
};
对前面委托的一堆动作执行后的一个描述
IAsyncResult asyncResult = func.BeginInvoke("Richard",callback, "Hugh");
int iResult= func.EndInvoke(asyncResult); //主线程会等待;到这儿来要拿结果的;要拿结果,必须只要执行完毕;
EndInvoke的用法
- EndInvoke可用来获取委托(带有返回值的委托,如Func)异步调用的返回值;
- 对于每一个异步操作,只能调用一次EndInvoke;
//对前面委托的一堆动作执行后的一个描述
IAsyncResult asyncResult = func.BeginInvoke("Richard",callback, "Hugh");
int iResult= func.EndInvoke(asyncResult); //主线程会等待;可获得函数的执行结果,要拿结果,必须只要执行完毕;
IAsyncResult的用法
- IAsyncResult 为对前面委托的一堆动作执行后的一个描述,可通过属性IsCompleted判断异步方法是否执行完成;
- AsyncCallback委托的方法参数也为IAsyncResult
限时等待时长的设置:
asyncResult.AsyncWaitHandle.WaitOne();//一直等待任务完成;
asyncResult.AsyncWaitHandle.WaitOne(-1);//一直等待任务完成,同上;
asyncResult.AsyncWaitHandle.WaitOne(2000); //限时等待:最多等待2秒,过时不候;会阻塞主线程;