Geeks With Blogs

@codingbloke
  • codingbloke Blogged: Using the AsyncOperationService with HttpWebRequest. Builds on the previous .NET Async Pattern stuff. http://t.co/B5VLg8a about 1088 days ago
  • codingbloke I haven't blogged in a while but http://t.co/jzEgzME its more on AsyncOperationService. Future posts will show more practical uses. about 1130 days ago
  • codingbloke @Pete_Brown I like "custom" mode, gives me the warm fuzzy feel that I'm in control about 1306 days ago

News
The Coding Bloke An ordinary bloke trying to keep up with the world of programming

This post is about using the AsyncOperationService with .NET Asynchronous PatternWarning: this is another article that is likely to give you a headache.  Its designed to provide full details of how things work.  If you don’t want the headache then, skim the article and copy’n’paste the code from the “FromAsyncPattern” box below (it assumes you already have AsyncOperationService code).  Subsequent articles will outline more real world uses which may (and I say “may” very tentatively) not be so headache inducing.

Concepts Recap

The objective of the AsyncOperationService is to allow developers to write code that appears to be synchronous even though it is in fact asynchronous. It does this by utilising the C# yield statement to convert what in pseudo-code is a synchronous sequence in to a list of AsyncOperation delegates that are then processed one after another by the AsyncOperationService.

What do we need?

We need to be able to take the Begin/End pair of methods that make up an asynchronous API feature and convert them into an AsyncOperation.  This is done by adding the following class to your project (assumes you already have the AsyncOperationService in the project).

FromAsyncPattern
using System;

namespace CodingBloke.AsyncOperations
{
    public static partial class AsyncOperationService
    {
        public static AsyncOperation FromAsyncPattern(Func<AsyncCallback, object, IAsyncResult> beginOp, Action<IAsyncResult> endOp)
        {
            return (completed) =>
            {
                AsyncCallback cb = (ar) =>
                {
                    try
                    {
                        endOp(ar);
                        completed(null);
                    }
                    catch (Exception err)
                    {
                        completed(err);
                    }
                };

                beginOp(cb, null);
            };
        }
        
        public static AsyncOperation FromAsyncPattern(Func<AsyncCallback, IAsyncResult> beginOp, Action<IAsyncResult> endOp)
        {
            return FromAsyncPattern((cb, o) => beginOp(cb), endOp);
        }
    }
}

 

If you’ve had a look a Microsoft’s Reactive Framework you may recognise this approach.  It takes two delegate parameters, one to begin the operation and another for the end of the operation.  The delegates have the most basic signature possible, one that matches an operation that takes no parameters and returns no value.  When AsyncOperation is execute the begin operation delegate is called and the callback it is provided with will invoke the end operation.  The call to the completed delegate is part of the AsyncOperationService plumbing to indicate that the next step can be taken.

How do we use it?

Lets just invent some nonsense .NET Asynchronous pattern interface.  It has two operations, a GetStringList which (surprisingly) returns a list of strings and a ProcessString which takes an input string and processes it in some unspecified way.   Using the .NET Asynchronous pattern the interface breaks both these operations into a Begin/End pair and ends up looking as follows.

Some Imaginary Interface
    public interface IMadeThisUp
    {
        IAsyncResult BeginGetStringList(AsyncCallback callback, object State);
        List<string> EndGetStringList(IAsyncResult asyncResult);

        IAsyncResult BeginProcessString(string input, AsyncCallback callback, object State);
        void EndProcessString(IAsyncResult asyncResult);
    }

 

Lets imagine that we need to retrieve a list of strings then process each of the strings in turn.  Yes I know its not the most realistic scenario but I’m trying to stick with the concepts for the moment.  In keeping with my methodology of writing a synchronous procedure first this is what such routine might look like if the interface contained the synchronous GetStringList and ProcessString methods.

Psuedo Synchronous Code
        public void GetAndProcessStrings()
        {
            IMadeThisUp processor = new SomeImplementor();

            List<string> valueList = processor.GetStringList();

            foreach (string value in valueList)
            {
                processor.ProcessString(value);
            }
        }

 

The above code is really straightforward, its very easy to look at that code reason out what its doing.  It would be nice if the real asynchronous version could look so straightforward.  Well it can’t but I think we can get close.  This what the asynchronous version looks like.

The Actual Asynchronous Code
        public IEnumerable<AsyncOperation> GetAndProcessStrings()
        {
            IMadeThisUp processor = new SomeImplementor();

            List<string> valueList = null;
            yield return AsyncOperationService.FromAsyncPattern(processor.BeginGetStringList, ar => valueList = processor.EndGetStringList(ar));

            foreach (string value in valueList)
            {
                yield return AsyncOperationService.FromAsyncPattern(cb => processor.BeginProcessString(value, cb, null), processor.EndProcessString);
            }
        }

 

If you are skimming to avoid headache just read this first paragraph

Fundamentally to go from “synchronous” to asynchronous code the function now returns an IEnumerable<AsyncOperation> that the AsyncOperationService can run.  At the points in the code where we need to change from the imaginary synchronous methods to using the Begin/End asynchronous pairs we are now yielding an AsyncOperation with the help of the FromAsyncPattern method.  Now here is the crucial aspect, even if a developer reading the above code had no idea how the AsyncOperationService works he or she would still be able to discern the intent of the code.  This is far cry from other asynchronous approaches which are almost entirely opaque until you grasp the asynch mechanisms involved.  This is especially true when loops are involved.

For the first operation, the GetStringList, the operation does not take any parameters, hence when calling FromAsyncPattern we can pass the BeginGetStringList directly to it since it conforms the most basic signature.  However since EndGetStringList returns a value it does not conform to the most basic signature.  Hence we pass in a lambda which does conform and which in turn calls the EndGetStringList assigning the returned value to the valueList variable.  Note valueList is assigned null initially, this is required by the C# compiler else it complains about the use of an unassigned variable.

If you are following this series of articles you will note this common pattern.  Where an ideal synchronous method would return a value (of type T) the asynchronous operation version must return an AsyncOperation instead so to compensate the final parameter passed to this asynchronous function will be an Action<T>.  It will be common to see a tight lambda of the form  r => resultVariable = r  passed to this parameter.  Any further processing of the returned value would then simply be placed following the call (and yield of) the asynchronous function just as it would have in synchronous code.

For the second operation, the ProcessString, the operation takes an additional String parameter and thus BeginProcessString does not conform to the most basic signature.  So in this case a lambda is passed to the FromAsyncPattern function’s first parameter.  It takes the standard AsyncCallback (cb) parameter and passes it in to the BeginProcessString along with the string value to be processed.  The EndProcessString method does conform to the most basic signature since it doesn’t return anything so in this case we can just pass it directly as the second parameter.

You might note that I’m not making any use of the “State” object that the .NET Asynchronous pattern places as the final parameter in the Begin methods which then appear as a property of the IAsyncResult.  In effect its the set of variables in the procedure which now form the “State”.  Whereas before we might pass an object instance around via the “State” object and at times we would even need to create a class to hold a set of properties needed from one call to the next.  All that is unnecessary when using AsyncOperationService, C# gives us all that for free via the yield statement and lambdas.

How is it called?

Very simply.

            GetAndProcessStrings().Run(err =>
            {
                if (err != null)
                {
                    // Final chance to deal with something bad that happened.
                }
            });

 

What’s next?

Ok so that was all very conceptual but how is it used in the real world?  In my next articles I’ll go into such uses starting with using the .NET Asynchronous Pattern API exposed be HttpWebRequest.

Posted on Saturday, August 27, 2011 6:20 PM Silverlight , AsyncOperationService | Back to top


Comments on this post: Using AsyncOperationService with the .NET Asynchronous Pattern

No comments posted yet.
Your comment:
 (will show your gravatar)
 


Copyright © codingbloke | Powered by: GeeksWithBlogs.net | Join free