Use of IAsyncResult.AsyncWaitHandle - c#

In the asynchronous programming model, there looks to be 4 ways (As stated in Calling Synchronous Methods Asynchronously) for making asynchronous method calls.
Calling the EndInvoke() method makes the calling thread wait for the method completion and returns the result.
Going through the IAsyncResult.AsyncWaitHandle.WaitOne() also seem to do the same. AsyncWaitHandle gets a signal of completion (In other word the main thread waits for the Asynchronous method's completion). Then we can execute EndInvoke() to get the result.
What is the difference between calling the EndInvoke() directly and calling it after WaitOne()/WaitAll()?
In the polling technique we provide time for other threads to utilize the system resources by calling Thread.Sleep().
Does AsyncWaitHandle.WaitOne() or EndInvoke() make the main thread go on sleep while waiting?

Q1. There is no difference in the way your code runs or your application, but there might be some runtime differences (again not sure, but a guess based my understanding of Async delegates).
IAsyncResult.AsyncWaitHandle is provided mainly as a synchronization mechanism while using WaitAll() or WaitAny() if you dont have this synchronization need you shouldn't read AsyncWaitHandle property. Reason : AsyncWaitHandle doesnt have to be implemented (created) by the delegate while running asynchronously, until it is read by the external code. I'm not sure of the way CLR handles the Async delegates and whether it creates a WaitHandler or not, but ideally if it can handle running your async delegates without creating another WaitHandle it will not, but your call to WaitOne() would create this handle and you have extra responsibility of disposing(close) it for efficient resource release. Therefore recommendation would be when there is no sycnchronization requirement which can be supported with WaitAll() or WaitAny() dont read this property.
Q2. This Question answers the difference between Sleep and Wait.

Simple things first. For your second question, yes, WaitOne and EndInvoke does indeed make the current thread sleep while waiting.
For your first questions, I can immediately identify 2 differences.
Using WaitOne requires the wait handle to be released, while using EndInvoke directly doesn't require any cleanup.
In return, using WaitOne allows for something to be done before EndInvoke, but after the task has been completed.
As for what that "something" might be, I don't really know. I suspect allocating resources to receive the output might be something that would need to be done before EndInvoke. If you really have no reason to do something at that moment, try not to bother yourself with WaitOne.

You can pass a timeout to WaitOne, so you could, for instance want to perform some other activities on a regular basis whilst waiting for the operation to complete:
do {
//Something else
) while (!waitHandle.WaitOne(100))
Would do something every ~100 milliseconds (+ whatever the something else time is), until the operation completed.

Related

HttpWebRequest.BeginGetResponse callback on the same thread

Is it possible that a call to a Begin... method (that takes a callback and an object and returns an IAsyncResult), specifically HttpWebRequest.BeginGetResponse, will call the callback on the same thread, thus if not handled correctly will cause a hang in case the callback releases a wait-handle?
If so, what is the best way to handle that case? Should I use the return value to make sure the request was already handled and release the wait-handle (or not wait on it in the first place)? Will the callback be called in such case?
I know it happens for sure with HttpWebRequest.BeginGetRequestStream (I learned it the hard way). But is it possible it'll happen with HttpWebRequest.BeginGetResponse also?
What I'm facing are rare hangs of the test suite and I narrowed it down to the communication library, where (unless I missed something) all relevant communication are being done asynchronously with HttpWebRequest.BeginGetResponse and AutoResetEvent for wait handles.

How much of a performance hit is there when calling async methods that are immediately waited on?

A lot of API's are moving toward exposing only asynchronous methods. How much of a performance hit is there in scenarios where you have to immediately wait on these methods? Am I wrong in assuming that it causes the current thread to wait on a spawned thread to complete? Or does the CLR perform some sort of magic in these scenarios and make it all execute in the same thread?
By "asynchronous methods", I assume you mean Task<T> based async methods.
So if you have a method that returns a Task<T> and you immediately call its Wait() method, that causes the current that to wait on an internal WaitHandle object. The task most likely executes on a different thread and signals the WaitHandle when completed, which releases the waiting thread. There is no compliler optimization that turns this scenario into a synchronous call that I'm aware of.
This is of course more work than just calling a synchronous equivalent of the async method. However,depending on your use case, it probably won't be a significant difference.
The more important question is why would you want to loose the advantages of async by blocking the calling thread? That is generally not a good idea, you should ensure you have a very good reason to do this.

What does it mean for a method to be asynchronous?

What is an asynchronous method. I think I know, but I keep confusing it with parallelism. I'm not sure what the difference between an asynchronous method is and what parallelism is.
Also what is difference between using threading classes and asynchronous classes?
EDIT
Some code demonstrating the difference between async, threading and parallelism would be useful.
What are asynchronous methods?
Asynchronous methods come into the discussion when we are talking about potentially lengthy operations. Typically we need such an operation to complete in order to meaningfully continue program execution, but we don't want to "pause" until the operation completes (because pausing might mean e.g. that the UI stops responding, which is clearly undesirable).
An asynchronous method is one that we call to start the lengthy operation. The method should do what it needs to start the operation and return "very quickly" so that there are no processing delays.
Async methods typically return a token that the caller can use to query if the operation has completed yet and what its result was. In some cases they take a callback (delegate) as an argument; when the operation is complete the callback is invoked to signal the caller that their results are ready and pass them back. This is a commonly used callback signature, although of course in general the callback can look like anything.
So who does actually run the lengthy operation?
I said above that an async method starts a length operation, but what does "start" mean in this context? Since the method returns immediately, where is the actual work being done?
In the general case an execution thread needs to keep watch over the process. Since it's not the thread that called the async method that pauses, who does? The answer is, a thread picked for this purpose from the managed thread pool.
What's the connection with threading?
In this context my interpretation of "threading" is simply that you explicitly spin up a thread of your own and delegate it to execute the task in question synchronously. This thread will block for a time and presumably will signal your "main" thread (which is free to continue executing) when the operation is complete.
This designated worker thread might be pulled out of the thread pool (beware: doing very lengthy processing in a thread pool thread is not recommended!) or it might be one that you started just for this purpose.
First off, what is a method and what is a thread? A method is a unit of work that either (1) performs a useful side effect, like writing to a file, or (2) computes a result, like making a bitmap of a fractal. A thread is a worker that performs that work.
A method is synchronous if in order to use the method -- to get the side effect or the result -- your thread must do nothing else from the point where you request the work to be done until the point where it is finished.
A method is asynchronous if your thread tells the method that it needs the work to be done, and the method says "OK, I'll do that and I'll call you when it is finished".
Usually the way an asynchronous method does that is it makes another worker -- it grabs a thread from the pool. This is particularly true if the method needs to make heavy use of a CPU. But not always; there is no requirement that an asynchronous method spins up another thread.
Does that make sense?
Say you need to clean the house, cook the dinner and put the children to bed.
Synchronous:
You clean the house, then cook dinner, then put the children to bed.
Parallel:
You hire 3 people to clean the house, cook dinner and put the children to bed. But you don't trust them so keep a supervisory role, looking over them and waiting for them to finish. Only when they've all finished do they get paid.
Asynchronous:
You one child to clean the house and another to cook dinner. When each have finished their chores they put themselves to bed, while you put your feet up with a glass of wine in front of the tv.
First you got to understand that if you want parallelism all the structure need to be parallel, I mean that if you have an asynchronous method you need a asynchronous call.
In webservices or web stuff, asynchronous methods can be (just one of the many ways) called with AJAX which is asynchronous. In one method you can have multiple threads, this is the key difference between async methods and multiplie threads.
And the main: the difference between a standard method and a async method is that if you make 2 calls to a standard method at the same time to the same controller with a asynchronous caller (like AJAX) the second call will just begin when the first call has already completed, if the methods that you called were asynchronous both the calls will begin at the same time, with multiple-cores servers it can achiev twice (2 calls) the standard speed.
The speed of the parallelism is measured by this law.

Async methods don't require additional threads?

In MSDN, there is a paragraph like this:
The async and await keywords don't cause additional threads to be
created. Async methods don't require multithreading because an async
method doesn't run on its own thread. The method runs on the current
synchronization context and uses time on the thread only when the
method is active. You can use Task.Run to move CPU-bound work to a
background thread, but a background thread doesn't help with a process
that's just waiting for results to become available.
But it looks I need little more help with the bold text since I am not sure what it exactly means. So how come it becomes async without using Threads?
Source: http://msdn.microsoft.com/en-us/library/hh191443.aspx
There are many asynchronous operations which don't require the use of multiple threads. Things like Asynchronous IO work by having interrupts which signal when data is available. This allows you to have an asynchronous call which isn't using extra threads - when the signal occurs, the operation completes.
Task.Run can be used to make your own CPU-based async methods, which will run on its own separate thread. The paragraph was intended to show that this isn't the only option, however.
async/await is not just about using more threads. It's about using the threads you have more effectively. When operations block, such as waiting on a download or file read, the async/await pattern allows you to use that existing thread for something else. The compiler handles all the magic plumbing underneath, making it much easier to develop with.
See http://msdn.microsoft.com/en-us/magazine/hh456401.aspx for the problem description and the whitepaper at http://www.microsoft.com/en-us/download/details.aspx?id=14058.
Not the code generated by the async and await keyword themselves, no. They create code that runs on your the current thread, assuming it has a synchronization context. If it doesn't then you actually do get threads, but that's using the pattern for no good reason. The await expression, what you write on the right side of the await keyword causes threads to run.
But that thread is often not observable, it may be a device driver thread. Which reports that it is done with a I/O completion port. Pretty common, I/O is always a good reason to use await. If not already forced on you by WinRT, the real reason that async/await got added.
A note about "having a synchronization context". You have one on a thread if the SynchronizationContext.Current property is not null. This is almost only ever the case on the main thread of a gui app. Also the only place where you normally ever worry about having delays not freeze your user interface.
Essentially what it's doing is when you run an async method without calling it with await is this:
Start the method and do as much as possible sychronously.
When necessary, pause the method and put the rest of it into a continuation.
When the async part is completed (is no longer being waited on), schedule the continuation to run on the same thread.
Whatever you want can run on this thread as normal. You can even examine/manipulate the Task returned from the async method.
When the thread becomes available, it will run the rest of your method.
The 'async part' could be file IO, a web request, or pretty much anything, as long as calling code can wait on this task to complete. This includes, but is not limited to, a separate thread. As Reed Copsey pointed out, there are other ways of performing async operations, like interrupts.

Performance cost of using the IAsyncResult overload of Task.FromAsync

I'm trying to wrap some existing APM calls (BeginX, EndX) in Tasks to get all the nice benefits of them. Unfortunately, our methods are unconventional and use out parameters and so can't use the standard FromAsync method where you give it both the begin and end delegates and let it wrap it nicely.
This article describes the alternative: an overload that takes an IAsyncResult and only requires you to implement the end callback. They take the IAsyncResult handle, then wait until it completes, then call the delegate you passed in.
This seemed fine, but then I read another article about wrapping APM calls in tasks. He also mentions that the IAsyncResult overload is not as efficient as the other methods. It seems to me like this means that the callback is not used to report completion of the method. That means they must be using the AsyncWaitHandle or polling IsCompleted. Which one do they use? How much performance penalty is it?
If it's doing polling that means the callback might not come right away and they have to busily check it during the whole call. If they've got an AsyncWaitHandle, they have another thread sitting and waiting on the result, which completely defeats the point of using an asynchronous method for me.
Does anyone know what they're doing and how severe this performance penalty is?
Does anyone know what they're doing and how severe this performance penalty is?
It's not incredibly severe, but there is more overhead. Since you aren't providing them the same information (only the IAsyncResult), the implementation has to call ThreadPool.RegisterWaitForSingleObject to trigger a callback when the IAsyncResult completes.
When this isn't used, and the Begin/End pair + callback exist, the callback automatically can trigger the completion of the task, eliminating the extra wait call here. This effectively ties up a ThreadPool thread to block (WaitOne) on the wait handle until the operation completes. If this is a rare occurrence, the performance overhead is probably negligible, but if you're doing this a lot, it could be problematic.
Looking at the code in JustDecompile, it creates a TaskCompletionSource wrapping the IAsyncObject, which creates a new Task, which probably means a thread waiting for the IAsyncObject to complete. Not ideal, but it's probably the only way to do it since there is no way to make a good one-size-fits-all polling rate.
When you pass in a ISyncResult there is no way for TaskFactory to insert a callback back. So the TaskFactory needs the ISynResult spin up a WaitHandle, and needs the ThreadPool to get a thread to wait on this handle. There is no polling involved.
Arrived here because I had a similar problem (with out parameters), but only on the End method. This is what I came up with, it might be helpful to someone:
var provider = new Provider();
return Task<Whatever>.Factory.FromAsync(provider.Begin, ar =>
{
Whatever outparam;
provider.End(out outparam);
return outparam;
}, state);
It compiles :)

Categories