2

Let's say I have this code :

  public class MyAsyncHandler : IHttpAsyncHandler
    {
      public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
      {
        MyAsynchOperation asynch = new MyAsynchOperation(cb, context, extraData);
        asynch.StartAsyncWork();
        return asynch;
      }
     //...

Now , if MyAsynchOperation is an IO operation , so it probably have internal methods (APM) of BeginFOO/EndFOO which are not tying a thread.

When the operation is finished , a new/same thread from the thread pool (via completion ports) is dealing with the response.

All ok.

But one of the things which makes me wonder is that IAsyncResult has this property :

System.Threading.WaitHandle AsyncWaitHandle { get; }

I'm familiar with WaitHadnle that it has a methods to block the current thread.
A thread waits, or blocks, at the turnstile by calling WaitOne (for example).

And so here is my questions :

Question #1

  • Assuming MyAsynchOperation is using the APM for IO , How(for what) does waitHAndle is being used if there is no blocking/tying a thread ?

Question #2

  • Assuming MyAsynchOperation is NOT using the APM and it's just my implementation which internally calls new Thread().start(do some calculation) which I later later call AsyncCallback's Callback ---- does waithandle here blocks a thread ?
Royi Namir
  • 144,742
  • 138
  • 468
  • 792

1 Answers1

2

#1:

The entire point of WaitOne here is to allow people to write synchronous code that waits for completion; if you don't need to use methods like WaitOne, WaitAny etc - then don't use them; that's fine.

#2:

In both cases, whether it uses a dedicated thread, or whether it completes via some other callback, yes it blocks a thread: it blocks the thread that has requested to be blocked by calling WaitOne. If you don't want that: don't call WaitOne.


Aside: since you specify 4.0, you might find it more intuitive to return a Task<T> instead, using TaskCompletionSource<T>. Edit: I realize now that this isn't an option due to satisfying the IHttpAsyncHandler.BeginProcessRequest method.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Thanks for reply Marc, but still regarding #1 , I know whta's the purpose of waithandle , But I also know that APM is not tying/blocking a thread (io operation) . so how come this happens ? – Royi Namir Apr 15 '14 at 13:57
  • @RoyiNamir how come what happens? Please be specific. – Marc Gravell Apr 15 '14 at 13:58
  • how come waitHandle is used in IAsyncResult for IO operations without blocking where , waithandle DOES blocks ? – Royi Namir Apr 15 '14 at 13:59
  • @RoyiNamir `WaitHandle` only blocks if it is requested to do so; you can use `IAsyncResult` without ever touching `WaitHandle`. It is there to *allow* certain patterns of use. It isn't used for every scenario. – Marc Gravell Apr 15 '14 at 14:01
  • @RoyiNamir no, the **most common** pattern is that the caller passes in a callback (`cb`) that is invoked when the work is complete. The caller then calls `End*` passing in the `IAsyncResult` token, and gets the reply. I think I've used `WaitHandle` once, maybe twice. – Marc Gravell Apr 15 '14 at 14:05
  • Marc, so in your last comment , the caller thread was not blocking ...right ? – Royi Namir Apr 15 '14 at 14:12
  • @RoyiNamir correct; the original thread called `Begin*` then went away to do something else. The callback most likely won't even happen on the same thread. Unless of course the completion is actually synchronous (there's a flag for that - `CompletedSynchronously`) – Marc Gravell Apr 15 '14 at 14:13
  • Marc , but what if the original thread calls myBeginxxx which is not (!) doing IO , but just sleep for a sec , would the calling (!) thread would be blocked ? .....(im trying to figure if it's also wont block on a non-IO operation)... – Royi Namir Apr 15 '14 at 15:10
  • @RoyiNamir that depends when the "just sleep for a sec" happens. If that happens inside the `Begin*`, then yes of course it will be blocked. If it happens *separately*, then of course it won't be blocked. – Marc Gravell Apr 15 '14 at 15:18
  • Mybeginxxx is calling sleep . But i asked about the calling thread which runs mybeginxxx , would it be blocked ? – Royi Namir Apr 15 '14 at 15:21
  • @Royi if you are still on the calling thread: then yes. If you aren't: then no. If the sleep happens before the caller exits the Begin* method, then yes it will be blocked for the duration of the sleep. What else could possibly happen? (Edit: at least without "await" rewriting the method) – Marc Gravell Apr 15 '14 at 15:36
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/50707/discussion-between-royi-namir-and-marc-gravell) – Royi Namir Apr 15 '14 at 15:50
  • Marc , regarding your edit, i've just noticed that Task implements IasyncResult , so basically i could return cast to IasyncResult .... No ? – Royi Namir Apr 18 '14 at 07:03
  • @Royi interesting. I've never tried it. Let me know how that works out. – Marc Gravell Apr 18 '14 at 08:06