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:
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.