locked
Is there a pattern for wrapping existing BeginXXX/EndXXX async methods into async tasks?

    Question

  • Is there a pattern for wrapping existing BeginXXX/EndXXX async methods into async tasks?

    I'm thinking primarily of Async Socket programming.

     

    Friday, October 29, 2010 12:33 AM

Answers

  • Yes.  In .NET 4, the Task Parallel Library includes a built in wrapper for the APM pattern (Begin/End): Task.Factory.FromAsync.  For example, if you wanted to create a task for a call to Stream's BeginRead/EndRead method, you could do:

    Stream s = ...;
    byte [] buffer = ...;
    Task<int> numBytesRead = Task<int>.Factory.FromAsync(s.BeginRead, s.EndRead, buffer, 0, buffer.Length, null);
    // or with await
    int numBytesRead = await Task<int>.Factory.FromAsync(s.BeginRead, s.EndRead, buffer, 0, buffer.Length, null);

    Under the covers, FromAsync is just built on top of TaskCompletionSource<TResult>.  A simple version of FromAsync for this read example would look something like:

    var tcs = new TaskCompletionSource<TResult>();
    s.BeginRead(buffer, 0, buffer.Length, iar =>
    {
        try { tcs.SetResult(s.EndRead(iar)); }
        catch(Exception exc) { tcs.SetException(exc); }
    }, null);
    Task<int> numBytesRead = tcs.Task;

    I hope that helps.

    Friday, October 29, 2010 1:30 AM