【转载】多线程并发难以掌控?学会这4招很轻松!

[软谋.net] Eleven 2018/10/26 8:46:26

【前言】

    上一篇总结了异步多线程的三大特点,不卡界面,速度快,但就是难以掌控顺序,无法预测线程之间的先后顺序,这局限了很多场景下多线程的应用!因为线程是计算机资源,更多的来说是受操作系统调度管理的,虽说如此,但是也有些方式可以驾驭部分的,下面Eleven将为大家总结异步委托的多种顺序控制方式!

1
【异步回调】
     通过委托异步调用,我们可以让一个耗时的操作由子线程完成,不卡界面,但业务可能要求在这个长时间操作完成后,执行一个后续动作,怎么样来保证呢?异步回调帮助你,上代码: 





可以实例化一个如图AsyncCallback的带一个IAsyncResult类型参数的没有返回值的委托,将需要后续执行的动作放入其中,然后传递给异步调用的倒数第二个参数。运行后会看到结果,回调动作一定是在异步执行完后执行,而且是由子线程来完成回调的!


异步委托的最后一个参数是状态参数,会自动保存到AsyncState属性,主要是提供给回调使用,可以放入任何对象!


此外,在图中还展示了一个情况,callback的调用参数,实际上就是异步调用委托的一个描述结果,asyncResult!


通过异步回调,可以做到保证某个动作一定在异步动作完成后执行!来个小思考题,如果是多个异步调用,然后有一个回调动作,又该如何处理呢?(底部扫码关注公众号,回复“异步回调答案”,可以看到Eleven老师的答案)!

 



2
【等待完成】
     除了回调式执行后续操作,也有时候我们需要确定操作完成后,才允许用户进一步完成别的操作,才允许主线程返回,这种又该如何处理呢?当然单线程是不够的,因为用户只是卡死。下面看看基于IsCompleted的等待:





看运行结果发现,确实做到了在任务完成后再返回操作成功,这种情况下,界面是会被卡主不能执行别的操作,但同时我们也能给用户一些类似于进度条的提升,去改善用户体验!


这里有个小坑,就是线程等待可能最高有200ms的延迟,因为我们是判断属性后进行等待200ms,存在误差~ 



3
【信号量等待】
     假如我不想有这种延迟呢?可以基于AsyncWaitHandle的信号量方式:



  


这里可以做到等待,而且任务完成后立即下一行,不会有延迟。这里当然也是要卡主界面的,因为UI线程在忙于等待,而且这里不能再去提示进度条了?But这有啥意义?可以边执行计算,边执行别的内容,然后在等待,让任务并行起来!


这里还有个特殊的方法是WaitOne指定具体的毫秒数,可以做到最多等待多久,然后就放弃等待,在很多场景下可以去做一些超时控制。 




4
异步返回值
      还有种简单的等待方式,是委托内置的方法EndInvoke,跟上面的WaitOne效果一致:





不过EndInvoke可不止是做这件事儿,还能做到获取带返回值的委托,在异步调用后,最终计算的真实结果。


 

注意:这里还有个小细节,EndInvoke不能重复调用,一个IAsyncResult只能被EndInvoke一次,否则会有异常提示。此外,EndInvoke还能加快完成异步线程资源的回收!




【结语】

异步多线程的顺序虽然不能完全掌控,但是在可空范围内,我们已经可以做到很多了,上文列出了四种方式去控制动作执行顺序,此外其实还有些办法去控制的。希望小伙伴儿们能通过本文学会最常见的几种控制顺序的方法,在今后的多线程使用中能得心应手!欢迎关注公众号,欢迎讨论,欢迎转发,愿天下有需求的人都能看到!


看完本文有收获?请转发分享给更多人

关注「.net学院」,提升.Net技能 






原文地址: https://www.opengps.cn/Blog/View.aspx?id=189 文章的更新编辑依此链接为准。欢迎关注源站原创文章!
文末推荐: 阿里云代金券礼包,感谢领取支持本文!!

暂不开启留言板块

鲁ICP备14008001号-2