0

由于各种原因,我一直致力于更改现有的同步 IO 绑定代码,例如在我们使用的服务中非常频繁地使用 HttpWebRequest 类发送出站 HTTP 请求。

我知道 async/await 以及对 .NET 4.5 的更改,但我们目前使用的是 .NET 4.0。我也知道 Microsoft.Bsl.Async,并且由于其他原因,目前这不是一个选项。

我正在使用This Article on Async 中的示例代码,并使用 HttpWebRequest作为参考。

我的问题是,如果我不更新 UI,或者在 BeginXXXX 和 EndXXXX 之间做其他事情,但是出站 IO 调用的时间是 40+ 秒,是否值得实现这个异步,或者我应该坚持同步执行?

4

1 回答 1

0

我会说这绝对值得。这是一个主观判断调用,尤其是在服务器端,但 40 秒是相当重要的。假设您的服务不受 CPU 限制,我会说大约 0.5 秒就足够快了,您可以考虑使其同步。40 秒,绝对是异步的。

如果您在 ASP.NET 上使用 .NET 4.0,则不能使用Microsoft.Bcl.Async. 但是,如果您的服务是其他东西(例如,Win32 服务),那么您可以使用Microsoft.Bcl.Async. 无论哪种方式,都计划在可能的情况下升级到 .NET 4.5。你将要知道多少痛苦async可以拯救你。

关于您的代码结构,我推荐以下两种方法之一:

  1. 使用基于事件的异步模式 (EAP)
  2. Task围绕异步编程模型 (APM) API使用包装器。

EAP 方法更简洁。使用 EAP,您将WebClient使用HttpRequest. 例如,调用DownloadStringAsync方法并处理DownloadStringCompleted事件。这样做的好处是 EAP 将通知您当前的上下文正在进行异步操作,在操作完成时再次通知它,并使用该上下文执行事件处理程序。如果您托管在 ASP.NET 中,这一点尤其重要。

EAP 模式的缺点是它总是使用上下文(即使您不需要它)。

TaskAPM 包装器方法需要做更多的工作。使用这种方法,您可以使用/对TaskFactory.FromAsync创建Task-returning 方法。然后使用返回的成员来安排完成 ( )。BeginEndTask<T>Task.ContinueWith

APM 包装器方法的缺点Task是它从不使用上下文,因此如果您托管在 ASP.NET 上,则需要执行自己的通知 ( SynchronizationContext.OperationStarted, SynchronizationContext.OperationCompleted)。您还(可能)必须捕获上下文 ( TaskScheduler.FromCurrentSynchronizationContext) 并将其传递给ContinueWith您安排延续时,以便它们在该上下文中运行。

如果您正在创建一个实际的组件供其余代码使用,那么TaskAPM 包装器方法确实有另一个优势:它更容易转换为/使用的基于任务的异步模式asyncawait

于 2013-07-22T19:15:39.980 回答