C# sync/async 同步/异步

同步方法api

1             Console.WriteLine($"****************Sync Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
2             Action<string> action = this.DoSomething;
3             for (int i = 0; i < 5; i++)
4             {
5                 string name = string.Format($"Sync_{i}");
6                 action.Invoke(name); //等价 方法直接执行 this.DoSomething(name);
7             }
8             Console.WriteLine($"****************Sync  End  {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
View Code

异步方法多线程

1             Console.WriteLine($"****************Async Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
2             for (int i = 0; i < 5; i++)
3             {
4                 var name = $"Async_{i}";
5                 action.BeginInvoke(name,null,null);
6             }
7             Console.WriteLine($"****************Async  End  {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
View Code
 1         /// <summary>
 2         /// 一个比较耗时耗资源的私有方法
 3         /// </summary>
 4         private void DoSomething(string name)
 5         {
 6             Console.WriteLine($"****************{name} Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
 7             long lResult = 0;
 8             for (int i = 0; i < 1_000_000; i++)
 9             {
10                 lResult += i;
11             }
12             Thread.Sleep(2000);
13             Console.WriteLine($"****************{name} Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
14         }
View Code

运行上面的代码,咱们发现几个问题:并发

一、同步方法卡界面:主线程(UI线程)忙于计算,无暇他顾 ;异步多线程方法不卡界面:主线程闲置,计算任务交给子线程完成异步

二、同步方法慢,只有一个线程计算;async

     异步多线程方法快,由于5个线程并发计算   差很少5倍,也不到5倍,CPU密集型计算(资源受限)ide

     多线程实际上是资源换性能,1 资源不是无限的  2 资源调度损耗性能

三、同步方法有序进行;this

      异步多线程无序spa

      启动无序:线程资源是向操做系统申请的,由操做系统的调度策略决定,因此启动顺序随机操作系统

      执行时间无序:同一个任务同一个线程,执行时间也不肯定,CPU分片

      结束无序:以上相加,结束也无序

AsyncCallback 异步回调:将后续动做经过回调参数传递进去,子线程完成计算后,去调用这个回调委托

AsyncState 用户定义对象:能够做为回调的参数

1             Console.WriteLine($"****************Async Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
2             AsyncCallback callback = ar => Console.WriteLine($"{nameof(AsyncCallback)} 是否完成:{ar.IsCompleted} 用户定义对象:{ar.AsyncState} {Thread.CurrentThread.ManagedThreadId.ToString("00")}");
3             for (int i = 0; i < 5; i++)
4             {
5                 var name = $"Async_{i}";
6                 action.BeginInvoke(name, callback, i);
7             }
8             Console.WriteLine($"****************Async  End  {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
View Code

IAsyncResult 对异步调用操做的描述

IsCompleted 断定异步任务是否完成

while (!asyncResult.IsCompleted) //if(!asyncResult.IsCompleted)
{
      // Do SomeThing
}

WaitOne 等待,即时等待  限时等待

asyncResult.AsyncWaitHandle.WaitOne();//直接等待任务完成
asyncResult.AsyncWaitHandle.WaitOne(-1);//一直等待任务完成
asyncResult.AsyncWaitHandle.WaitOne(1000);//最多等待1000ms,超时就不等了

EndInvoke 即时等待,并且能够获取委托的返回值 一个异步操做只能End一次

 1             Func<int, int> func = Sum;
 2             func.BeginInvoke(10, ar => {
 3                 Console.WriteLine($"线程ID:{ Thread.CurrentThread.ManagedThreadId.ToString("00")} 计算结果:{func.EndInvoke(ar)}");
 4             }, null);
 5 
 6 
 7             IAsyncResult asyncResult = func.BeginInvoke(5,ar =>
 8             {
 9                 //int iEndResultIn = func.EndInvoke(ar);
10             }, null);
11             int iEndResult = func.EndInvoke(asyncResult);
View Code

EndInvoke 能够写在BeginInvoke里也能够写在外面 但只能写一次 不然会报错

微软文档:

IAsyncResult:https://docs.microsoft.com/zh-cn/dotnet/api/system.iasyncresult?view=netframework-4.8

AsyncCallback:https://docs.microsoft.com/zh-cn/dotnet/api/system.asynccallback?view=netframework-4.8