【问题标题】:Implementing HttpWebRequest Async Methods实现 HttpWebRequest 异步方法
【发布时间】:2013-07-22 18:04:34
【问题描述】:

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

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

我使用来自This Article on Async with HttpWebRequest 的示例代码作为参考。

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

【问题讨论】:

  • 我很好奇为什么 Microsoft.Bsl.Async 不是一个选项。但是,如果某些东西值得实施,那么你愿意让你的用户通过、资源和其他几个指标(了解这些指标就是开发人员的全部意义所在),我认为这里的任何人都无法真正为您确定。

标签: c# .net asynchronous iasyncresult


【解决方案1】:

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

如果您在 ASP.NET 上使用 .NET 4.0,则不能使用 Microsoft.Bcl.Async。但是,如果您的服务是其他服务(例如 Win32 服务),那么您可以使用 Microsoft.Bcl.Async。无论哪种方式,都计划在可能的情况下升级到 .NET 4.5。您即将发现async 为您带来了多大的痛苦。

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

  1. 使用Event-based Asynchronous Pattern (EAP)
  2. Asynchronous Programming Model (APM) API 周围使用Task 包装器。

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

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

Task APM 包装方法需要更多工作。使用这种方法,您将使用 TaskFactory.FromAsync 围绕 Begin/End 对创建 Task-returning 方法。然后使用返回的Task<T> 上的成员来安排完成(Task.ContinueWith)。

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

如果您正在创建一个实际组件供其余代码使用,Task APM 包装器方法确实有另一个优势:它更容易转换为 async/@ 使用的 Task-based Asynchronous Pattern 987654346@.

【讨论】:

    猜你喜欢
    • 2012-08-30
    • 1970-01-01
    • 1970-01-01
    • 2015-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    相关资源
    最近更新 更多