Ben Biddington

Whatever it is, it's not about "coding"

Archive for December 2008

Asynchronous operations, what is EndInvoke for?

leave a comment »

When an exception is thrown on a worker thread, it does not appear on the parent thread unless EndInvoke is called.

[MSDN, How to call a Visual C# method asynchronously] The EndInvoke() function is used to retrieve the results of the asynchronous call. It can be called anytime after BeginInvoke(). If the asynchronous call has not completed yet, EndInvoke() blocks until it completes. The parameters of the EndInvoke() function includes the out and ref parameters that the wrapped function has, plus the IAsyncResult object that is returned by BeginInvoke().

There are four common ways to use BeginInvoke() and EndInvoke() to make asynchronous calls. After you call BeginInvoke(), you can:

  • Optionally do some other work and then use EndInvoke().
  • Obtain a WaitHandle that is provided by the IAsyncResult object, use its WaitOnemethod to block until the WaitHandle is signaled, and then call EndInvoke().
  • Poll the IAsyncResult object to determine when the asynchronous call has completed, and then call EndInvoke().
  • Have the system call a callback function that you specify. This callback function calls EndInvoke() and processes the results of the asynchronous call when it completes.

Note: It is an error to call EndInvoke more than once for an async operation.

The recommendations for implementing IAsyncResult state that setting is as completed should do things in a specific order. And that order has setting the wait handle happening before the callback is invoked.

Here’s an example EndInvoke implementation:

public void EndInvoke() {
    if (false == IsCompleted) {
        AsyncWaitHandle.WaitOne();
        AsyncWaitHandle.Close();
        asyncWaitHandle = null;
    }

    if (exception != null) {
        throw exception;
    }
}

This is starting to make sense — EndInvoke is a way to force control back  to the parent thread, since it blocks until the async operation has completed before returning. This is why exceptions are thrown from here if they occur — control has returned to the master thread.

[EDIT: 13-Sep-2009] Also, .NET Framework 2.0+, unhandled exceptions are not propagated to parent threads, i.e., child threads exit gracefully.

Written by benbiddington

3 December, 2008 at 21:37

Posted in development

Tagged with ,