May
19
2009

I have a much longer article in mind for this and will be publishing it out soon. But to quickly answer this let us use an implementation from the framework itself using a delegate. Please note, this is for a usage pattern sample only since all that a delegate does is put the work on the CLR’s thread pool which means more latency for non-blocking work.

Lets create a driver for our async operation which will define our little piece of work. Here we just return a string.


class AyncOperation
{
    // Your delegate to simulate an AsyncResult implementation
    static Func<string> operation = () => "Hello operation.";

    internal static IAsyncResult BeginOperation(AsyncCallback callback, object state)...
    internal static string EndOperation(IAsyncResult result)...
}

This is what is expected on the 2 paths that the code can complete on.

  • Synchronous Path
    • IAsyncResult result = BeginOperation()
    • Is Result.CompletedSynchronously  == true
      • Yes
        • Handle the completion like calling end etc.
        • Handle exceptions.
      • No
        • Do nothing and return
  • Callback
    • IS Result.CompletedSynchronously  == true
      • Yes
        • return as the sync path will take care of the rest
      • NO
        • Handle the completion
        • Handle exception if any

So here is the end to end implementation.

namespace Microsoft.Samples.SimpleDelegateAsyncResult { using System; using System.Threading; class Program { static AsyncCallback onCallback = new AsyncCallback(Callback); ManualResetEvent waitHanlde = new ManualResetEvent(false); static void Main(string[] args) { Program state = new Program(); try { IAsyncResult result = AyncOperation.BeginOperation(onCallback, state); if (result.CompletedSynchronously) { state.HandleCompletion(result); } } catch (Exception exception) { Console.WriteLine(" Exception : " + exception.Message); // Do the same exception handling here. state.waitHanlde.Set(); } state.waitHanlde.WaitOne(); state.waitHanlde.Close(); Console.WriteLine("Completed"); } static void Callback(IAsyncResult result) { if (result.CompletedSynchronously) return; Program thisPtr = result.AsyncState as Program; Exception completionException = null; try { thisPtr.HandleCompletion(result); } catch (Exception ex) { // Don't throw as you cannot bubble up exceptions on a callback thread completionException = ex; } finally { if (completionException != null) { // you need to handle exception here as well Console.WriteLine("Callback Exception : " + completionException.Message); } //release the main thread; thisPtr.waitHanlde.Set(); } } void HandleCompletion(IAsyncResult result) { Console.WriteLine(AyncOperation.EndOperation(result)); //throw new InvalidOperationException("test exception"); Thread.Sleep(100); } } class AyncOperation { // Your delegate to simulate an AsyncResult implementaion static Func<string> operation = () => "Hello operation."; internal static IAsyncResult BeginOperation(AsyncCallback callback, object state) { return operation.BeginInvoke(callback, state); } internal static string EndOperation(IAsyncResult result) { return operation.EndInvoke(result); } } }
Posted by sajay | Comments (0)| Permalink Categories: Microsoft |

Add comment




biuquote
  • Comment
  • Preview
Loading