Sim*_*one 4 c# asynchronous async-await
我有许多Utils类,我用于许多不同的项目,其中大多数是静态的,并且由静态方法构成,通常甚至不会相互调用.
我的目的是利用新的async/await功能,但不重写所有内容,所以我的问题是:我可以使用Task.Run(()=> MethodName)为每个名为MethodAsync的现有方法添加一个新方法吗?
例:
//old code that will not be removed
static void DoSomething()
{ ... }
//new code that will be added
static async Task DoSomethingAsync()
{
//not really sure if Im supposed to use await/async here.
//isn't Task awaitable even without async??
return await Task.Run(() => DoSomething());
}
Run Code Online (Sandbox Code Playgroud)
基本上在旧代码中我只有一个普通的同步方法,而在新代码中,我有一个异步方法,如果CLR将其视为CPU绑定方法,它甚至可以在另一个线程中运行.
如果我正确理解,每个异步方法都按定义包含等待一个等待的对象,这是一个Task或另一个异步方法.
这意味着每当我可以使用异步.NET方法时,我应该等待它并将我的调用方法标记为异步.
但是,应该使用Task.Run调用调用其他每个不调用任何异步方法但可能需要一些时间才能完成的方法.
对?
编辑
所以我已经阅读了所有发布的链接,msdn上的最佳实践和一些博客文章,但是在使用新的async/await功能进行编码时,我还需要一个完整的例程.这是我到目前为止所得到的:
1)每个具有异步备选方案的.NET方法都应该使用异步备选方法.(据我所知,.NET异步方法仅适用于可以异步的方法).
2)每个使用异步方法的方法也应该是异步的.
3)每个不使用异步方法的方法(因为没有可用)但仍然需要一些cpu-time来执行应该通过使用Task.Run包装来实现异步(我知道在这种情况下它应该是客户端如果他们想要使用Task.Run,但由于我只为执行时间超过50ms的方法添加这些包装器,并且仍然可以使用该方法的非异步版本,我仍然不明白为什么我不应该将此包装器放在库中).
4)每个采用非cpu-time的方法导致它等待其他源(如Internet,数据库,事件等)应该使用TaskFactory.FromAsync或TaskCompletionSource.
5)System.Threading.Tasks.Parallel.Invoke(method1,method2等等)现已弃用.从我读到的内容,如果CLR认为需要并发,Task.Run已经运行并发线程.因此,似乎Task.Run在需要时已经使用了Parallel.Invoke.
我终于找到了清除所有疑虑的好资源:
第一个是"基于任务的异步模式",可从http://www.microsoft.com/en-us/download/details.aspx?id=19957获得. 本文档解释了异步/等待功能,如何/何时到使用它,它包含许多实际示例和一些非常有用的静态方法,我现在正在每个项目中使用!
第二个是"async的禅:最佳性能的最佳实践",可在http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-829T获得, 它是异步功能的完整概述,有一些覆盖范围并行功能,它也解释了为什么它永远不应该是使用Task.Run()方法的库,但它应该是消费者的选择.
所以最后我真的把多线程与异步代码混淆了,我无法理解异步代码的优点,因为我当时只关注1个单一方法,而异步代码的真正好处只能在整个项目中看到(或至少其一致的部分)是在异步模式之后写入的.例如在asp.net中,如果没有任何阻塞代码(所有内容都以异步方式编写),那么一个线程可以服务另一个客户端,而你的等待异步操作,提高可伸缩性,而在xaml应用程序中一个线程启动异步操作可以立即返回到支持您的UI,而不是等待该操作结束,从而提高响应能力.
这已被讨论了,我应该揭露异步包装器同步的方法呢?我认为这篇文章的一部分强调了为什么这是一个糟糕的设计如下:
例如,考虑一个简单的方法
Dictionary<TKey,TValue>.Add(TKey,TValue).这是一种非常快速的方法,对吧?通常,是的,但请记住字典是如何工作的:它需要对密钥进行散列以便找到正确的存储桶,并且需要检查密钥与存储桶中已有的其他条目的相等性.那些散列和相等性检查可以导致对用户代码的调用,以及谁知道这些操作做了什么或者花了多长时间.字典上的每个方法都应该暴露异步包装吗?这显然是一个极端的例子,但有更简单的例子,如Regex.提供给Regex的正则表达式模式的复杂性以及输入字符串的性质和大小会对与Regex匹配的运行时间产生重大影响,以至于Regex现在支持可选的超时... Regex上的每个方法都有异步等价吗?我真的希望不是.
显然我建议你也阅读整篇文章,但我希望上面的内容强调了为什么暴露*Async()方法不应该在库中包含同步的方法.
我希望这有帮助.
| 归档时间: |
|
| 查看次数: |
1848 次 |
| 最近记录: |