我有一个外部库,该库的I / O速度很慢(串行+无线等),而API中没有异步(甚至是老式的)。
我正在尝试找到一种包装方法,以便从UI轻松使用,以便我的用户可以在不冻结整个UI的情况下进行连接,最好是async-await
。
但是我正在阅读有冲突的建议,例如“仅将Task.Run用于CPU绑定操作”。
那我该怎么办?只是async-await
和Task.Run
(省略ConfigurAwait(false)
)还是实现整个INotifyCompletion
?
答案 0 :(得分:7)
区分“理想”和“现实世界”很重要。理想情况下,async
应该一直存在。理想情况下,所有I / O应该是异步的,并且不会耗尽线程池线程,并且Task.Run
仅用于受CPU约束的方法。理想情况下,async void
仅应用于事件处理程序。
在现实世界中,有时由于时间不足(或图书馆支持),您不得不混用async
并进行同步。在现实世界中,并非所有I / O操作都具有异步API,甚至HttpClient
之类的崭新类型都使用线程池线程来解决旧的DNS解析代码,而没人愿意花时间来修复它。在现实世界中,async void
有时比裸露的延续更干净,即使它未用于事件处理程序也是如此。
就您而言,我只会使用Task.Run
而不必担心。 Task.Run
的主要问题是在ASP.NET应用程序或库中使用它时,它可能会干扰线程池的其他使用。由于您正在使用UI应用程序,因此使用Task.Run
进行I / O操作不是“理想的”方法,但这是一个很好的选择。