简体   繁体   English

实现HttpWebRequest异步方法

[英]Implementing HttpWebRequest Async Methods

For various reasons, I have been geared towards changing existing synchronous IO bound code such as sending outbound HTTP requests using the HttpWebRequest class very frequently in a service we use. 由于各种原因,我已经准备好更改现有的同步IO绑定代码,例如在我们使用的服务中非常频繁地使用HttpWebRequest类发送出站HTTP请求。

I am aware of async/await as well as the changes to .NET 4.5, but we are currently using .NET 4.0. 我知道异步/等待以及对.NET 4.5的更改,但是我们目前正在使用.NET 4.0。 I am also aware of Microsoft.Bsl.Async, and for other reasons, that is not currently an option. 我也知道Microsoft.Bsl.Async,并且由于其他原因,目前还不能选择。

I am using the example code from This Article on Async with HttpWebRequest as a reference. 我正在将本文的示例代码与HttpWebRequest用作异步参考。

The question I have is, if I am not updating a UI, or doing other stuff in between the BeginXXXX and EndXXXX, but the time of the outbound IO calls are 40+ seconds each, is it worth implementing this async, or should I stick to synchronous execution? 我的问题是,如果我不更新UI或在BeginXXXX和EndXXXX之间做其他事情,但是出站IO调用的时间各为40+秒,是否值得实现此异步,还是应该坚持同步执行?

I would say it's definitely worth it. 我会说绝对值得。 This is a subjective judgement call, especially on the server side, but 40 seconds is quite significant. 这是一个主观判断,尤其是在服务器端,但是40秒非常重要。 Assuming your service isn't CPU-bound, I'd say around 0.5 seconds is fast enough where you would consider making it synchronous. 假设您的服务不受CPU限制,我想说大约0.5秒足够快,您可以考虑使其同步。 For 40 seconds, definitely go asynchronous. 在40秒钟内,绝对要异步。

If you're on ASP.NET with .NET 4.0, then you can't use Microsoft.Bcl.Async . 如果您使用的是带有.NET 4.0的ASP.NET,则不能使用Microsoft.Bcl.Async However, if your service is something else (eg, a Win32 service), then you could use Microsoft.Bcl.Async . 但是,如果您的服务是其他服务(例如Win32服务),则可以使用Microsoft.Bcl.Async Either way, do plan to upgrade to .NET 4.5 when you can. 无论哪种方式,都请尽可能计划升级到.NET 4.5。 You're about to find out how much pain async saves you from. 您将要找出async痛苦为您节省了多少。

Regarding your code structure, I'd recommend one of two approaches: 关于您的代码结构,我建议使用以下两种方法之一:

  1. Use the Event-based Asynchronous Pattern (EAP) . 使用基于事件的异步模式(EAP)
  2. Use Task wrappers around the Asynchronous Programming Model (APM) APIs. 异步编程模型(APM) API周围使用Task包装器。

The EAP approach is cleaner. EAP方法更清洁。 With EAP, you'd use WebClient instead of HttpRequest . 使用EAP,您将使用WebClient而不是HttpRequest Eg, call the DownloadStringAsync method and handle the DownloadStringCompleted event. 例如,调用DownloadStringAsync方法并处理DownloadStringCompleted事件。 The advantages to this are that EAP will notify your current context that an asynchronous operation is in progress, notify it again when the operation completes, and use that context to execute the event handler. 这样做的好处是,EAP将通知您当前的上下文正在进行异步操作,在操作完成时再次通知它,并使用该上下文执行事件处理程序。 This is especially important if you are hosted in ASP.NET. 如果您托管在ASP.NET中,这尤其重要。

The disadvantage to the EAP pattern are that it always uses the context (even if you don't need it to). EAP模式的缺点是它始终使用上下文(即使您不需要)。

The Task APM wrapper approach is a bit more work. Task APM包装器方法需要更多工作。 With this approach, you'd use TaskFactory.FromAsync to create Task -returning methods around Begin / End pairs. 通过这种方法,您将使用TaskFactory.FromAsyncBegin / End对周围创建Task -returning方法。 Then use the members on the returned Task<T> to schedule completions ( Task.ContinueWith ). 然后使用返回的Task<T>上的成员安排完成时间( Task.ContinueWith )。

The disadvantage to the Task APM wrapper approach is that it never uses the context, so if you're hosted on ASP.NET you'd need to do your own notification ( SynchronizationContext.OperationStarted , SynchronizationContext.OperationCompleted ). Task APM包装器方法的缺点是它从不使用上下文,因此,如果您托管在ASP.NET上,则需要执行自己的通知( SynchronizationContext.OperationStartedSynchronizationContext.OperationCompleted )。 You would also (probably) have to capture the context ( TaskScheduler.FromCurrentSynchronizationContext ) and pass it to ContinueWith when you schedule your continuations so they run within that context. 您还可能(可能)必须捕获上下文( TaskScheduler.FromCurrentSynchronizationContext ),并在安排连续性以便它们在该上下文中运行时将其传递给ContinueWith

If you're creating an actual component that is used by the rest of your code, the Task APM wrapper approach does have another advantage: it is easier to convert to the Task-based Asynchronous Pattern used by async / await . 如果您要创建供其余代码使用的实际组件,那么Task APM包装器方法确实具有另一个优点:转换为async / await使用的基于任务的异步模式更容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM