学习笔记——异步

1.异步同步的定义多线程

同步方法:多个任务一个一个执行,同一时刻系统中只有一个任务在执行并发

异步方法:发起一个调用,并不等着计算结束,而是直接去运行下一行;刚才的计算,会启动一个新的线程去执行异步

 

2.异步同步的比较async

2.1. 同步方法卡界面,由于UI线程忙于计算;异步多线程方法不卡界面,主线程闲置,计算任务交给子线程在作;学习

2.2. 同步方法慢,只有一个线程计算;异步多线程方法快,多个线程并发计算;this

       多线程的资源消耗更多,线程并非越多越好(资源有限/管理线程也消耗资源)线程

2.3. 异步多线程是无序的:启动无序 执行时间不肯定  结束无序,,资源

       因此不要试图经过启动顺序或者时间等待来控制流程同步

 

3.异步如何控制执行顺序文件上传

3.1.回调

//IasyncResult,可用于监视调用进度

//DoSomethingLong方法名称(要执行的操做)

 Action<string> act = this.DoSomethingLong;

 IAsyncResult iAsyncResult = null;

 AsyncCallback callback = ar =>

 {

    // Console.WriteLine(object.ReferenceEquals(ar, iAsyncResult));

     Console.WriteLine(ar.AsyncState);

     Console.WriteLine($"这里是BeginInvoke调用完成以后才执行的。。。{Thread.CurrentThread.ManagedThreadId.ToString("00")}");

 };

 iAsyncResult = act.BeginInvoke("btnAsync_Click", callback, "异步学习");

3.2.等待

//IAsyncResult.IsCompeted肯定异步调用什么时候完成(轮询)

Action<string> act = this.DoSomethingLong;

IAsyncResult iAsyncResult = act.BeginInvoke("btnAsync_Click", null, null);

int i = 1;

while (!iAsyncResult.IsCompleted)//1 卡界面,主线程在等待   2 边等待边作事儿  3有偏差(时间)

{

    if (i < 10)

    {

        Console.WriteLine($"文件上传{i++ * 10}%。。。请等待");

    }

    else

    {

        Console.WriteLine("已完成99%。。。立刻结束");

    }

    Thread.Sleep(200);//偏差时间

}

Console.WriteLine("文件上传成功!!!");

3.3.状态

//使用 IAsyncResult.AsyncWaitHandle 获取 WaitHandle,使用它的 WaitOne 方法将执行一直阻塞到发出 //WaitHandle 信号,而后调用

Action<string> act = this.DoSomethingLong;

IAsyncResult iAsyncResult = act.BeginInvoke("btnAsync_Click", null, null);

//异步变同步(状态)

 iAsyncResult.AsyncWaitHandle.WaitOne();//一直等待任务完成,第一时间进入下一行

iAsyncResult.AsyncWaitHandle.WaitOne(-1);//一直等待任务完成,第一时间进入下一行

//最多等待1000ms,超时控制

iAsyncResult.AsyncWaitHandle.WaitOne(1000);//最多等待1000ms,不然就进入下一行,能够作一些超时控制

//调用 BeginInvoke 后可随时调用 EndInvoke 方法;若是异步调用未完成,EndInvoke 将一直阻塞到

//异步调用完成。

act.EndInvoke(iAsyncResult);//等待

 

4.其余相关知识

任何的异步多线程,都是跟委托相关。委托中的Invoke方法 是同步的。BeginInvoke开始一个异步的请求,调用线程池中一个线程来执行。

4.1.异步获取返回值

Func<int, string> func = i => i.ToString();

IAsyncResult iAsyncResult = func.BeginInvoke(DateTime.Now.Year, ar =>

 {

     string resultIn = func.EndInvoke(ar);//对于每一个异步操做,只能调用一次 EndInvoke。

     Console.WriteLine($"This is {ar.AsyncState} 的异步调用结果 {resultIn}");

 }, "异步参数");

//string result = func.EndInvoke(iAsyncResult);//获取返回值

5.小结

异步、同步和多线程的关系,能够这样理解下。

咱们把一个应用程序看作一家饭店的运做。单线程&多线程 看作是接待客人的服务员人数

饭店来客人后,一个客人一个服务员去接待(一个请求一个线程去处理),在此期间,服务员是一直陪着客人的。
可是当客人去吃饭的时候是不须要服务员的(好比程序去处理IO文件[系统的硬件进行操做]),此时该服务员闲着不干活(线程什么也没作,等待IO操做完毕)

上面的程序默认就是同步(一直陪着客人)的而异步是在客人吃饭的时候,服务员就不陪着了,而是去接待其余客人(处理其它请求),等客人吃完饭,再来一个服务员引导客人进行其它操做(线程池中的线程来处理)。

相关文章
相关标签/搜索