可以看到在Windows平台是通过IOCP触发回调事件。在Unix平台是在SocketAsyncEngine类创建while(true)循环的执行线程,再通过Wait epoll或kqueue获取IO事件,最后触发回调事件。IOPC为异步非阻塞IO、epoll为同步非阻塞IO,IOCP、epoll会涉及IO模型、IO多路复用等知识,网上介绍较多,可以自行查阅。同时需要注意AwaitableSocketAsyncEventArgs既继承SocketAsyncEventArgs类也实现IValueTaskSource接口。
HttpClient.GetStringAsync请求:
NetworkStream.WriteAsync在Windows平台实现:
NetworkStream.WriteAsync在Unix平台实现:
async await推荐实践方法
async/await适用于IO型(文件读取、网络通信)、延时型任务。对于计算型任务可以使用Task.Factory创建LongRunning任务,该任务会独立新建一个后台线程进行处理。
关于MySql驱动组件: 建议采用MySqlConnector组件。因为MySqlConnector组件支持异步IO,MySql.Data组件不支持真实的异步IO。
如果条件允许、尽量使用ConfigureAwait(false)。如果不设置在Winform场景下会调用SynchronizationContext.Post通过UI线程执行回调函数,同步方法调用异步方式时会出现死锁。
Task方法替代清单:
同步方法 异步方式 描述信息task.Wait await task 等待一个任务执行完成
task.Result await task 获取任务返回结果
Task.WaitAny await Task.WhenAny 等待其中一个任务执行完成,继续执行
Task.WaitAll await Task.WhenAll 等待所有任务执行完成,继续执行
Thread.Sleep await Task.Delay 延时几秒继续执行
附
Demo代码地址 : https://gitee.com/RiverBied/async-demo