简体   繁体   中英

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.

I am aware of async/await as well as the changes to .NET 4.5, but we are currently using .NET 4.0. I am also aware of Microsoft.Bsl.Async, and for other reasons, that is not currently an option.

I am using the example code from This Article on Async with HttpWebRequest as a reference.

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?

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. Assuming your service isn't CPU-bound, I'd say around 0.5 seconds is fast enough where you would consider making it synchronous. For 40 seconds, definitely go asynchronous.

If you're on ASP.NET with .NET 4.0, then you can't use Microsoft.Bcl.Async . However, if your service is something else (eg, a Win32 service), then you could use Microsoft.Bcl.Async . Either way, do plan to upgrade to .NET 4.5 when you can. You're about to find out how much pain async saves you from.

Regarding your code structure, I'd recommend one of two approaches:

  1. Use the Event-based Asynchronous Pattern (EAP) .
  2. Use Task wrappers around the Asynchronous Programming Model (APM) APIs.

The EAP approach is cleaner. With EAP, you'd use WebClient instead of HttpRequest . Eg, call the DownloadStringAsync method and handle the DownloadStringCompleted event. 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. This is especially important if you are hosted in ASP.NET.

The disadvantage to the EAP pattern are that it always uses the context (even if you don't need it to).

The Task APM wrapper approach is a bit more work. With this approach, you'd use TaskFactory.FromAsync to create Task -returning methods around Begin / End pairs. Then use the members on the returned Task<T> to schedule completions ( 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 ). 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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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