我有一个在.NET 4.0和VS2010中使用C#的.NET项目 .
我想做的是为我的库添加一些异步重载,以便使用await关键字为.NET 4.5中的用户更容易地执行异步编程 . 现在,正在重载的方法是非异步的 . 此外,我不想自己使用任何异步方法,只需创建新方法并使其可用 .
是否可以在.NET 4.0和VS2010中创建异步方法,如果是这样,.NET 4.0异步方法应该是什么样的?
因为我正在使用VS2010,所以我无法访问“async”关键字,因此需要在.NET 4.0中模拟这种行为?例如,它是否需要返回任何特定类型,并且是否需要在方法内部发生任何代码以使其调用的当前非异步代码异步发生?
3 回答
最简单的方法是返回
Task
或Task<T>
. 那就足够了 .但是,这只有在您的方法真正异步执行时才有意义 .
我还建议您遵循通常的命名模式,如AbcAsync(“Async”后缀) . 您的调用者不会注意到使用C#5创建的异步方法有任何差异(因为没有) .
提示:只是向方法添加异步不会做任何事情 . 您的方法将按顺序执行并返回已完成的任务 . 使方法返回任务必须服务于某个目的 - 通常这样做是因为该方法本身是异步执行的(如Web服务调用或文件IO) .
如果你的方法只包含计算但没有IO(或者只是阻塞IO),那么通常最好不要使它异步,因为你没有做到这一点 . 异步方法并不总是在单独的线程上执行 . 如果最后一句话让你感到惊讶,你可能想要深入研究一下这个话题 .
正如其他人所说,你首先要有一个方法返回
Task
或Task<TResult>
. 这足以await
在.NET 4.5中的结果 .要使您的方法尽可能适应未来的异步代码,请遵循Task-based Asynchronous Pattern document中的指南(也可用on MSDN) . 它提供命名约定和参数建议,例如,用于支持取消 .
为了实现您的方法,您有以下几种选择:
如果您已有基于
IAsyncResult
的异步方法,请使用Task.Factory.FromAsync .如果您有另一个异步系统,请使用TaskCompletionSource<TResult> .
只要您返回以某种方式完成的任务(无论是在线程中还是异步地),您都将支持异步模型 .
让异步执行任务是另一回事 . 如果您可以访问async关键字和API,则只需将方法基于对其他已提供的异步方法的异步调用 . 但在这种情况下,您必须手工制作异步任务 .
可能有更好的方法,但我能看到(并且已经使用过)最优雅的方法是利用
System.Threading.Tasks.TaskCompletionSource
来构造任务,使用Begin
/End
异步方法模型来执行您需要执行的任何操作 . 然后,当您掌握结果时,使用完成源将其发布到先前构造的Task
实例 .它肯定是异步的,只是不像即将发布的版本那样花哨 .
Disclaimer: 我不能接近这方面的专家 . 刚做了一些实验 .