Event-based Asynchronous Pattern (EAP)

The Event-based Asynchronous Pattern (EAP) is a specific design pattern to standardize event-based asynchronous programming features. Such a design is available in multiple classes from .NET itself and is available and suggested in all our implementations if applicable.

Unlike the previously seen APM, in this pattern, any method that supports synchronous execution will add an overloaded method for an asynchronous invocation. The result, instead, will be available only to a specific predefined callback method, one for each available method, within the class itself.

Here is an example showing the WebClient class downloading some web page data:

static void Main(string[] args)
{
    //a simple web client
    var client = new WebClient();

    //register for result callback
    client.DownloadDataCompleted += client_DownloadDataCompleted;

    //invoke asynchronous request
    client.DownloadDataAsync(new Uri("http://www.google.com"));

    Console.WriteLine("MAIN THREAD ENDED");
    Console.ReadLine();
}

static void client_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
    //this callback receives the whole response (data and status)

    //data
    byte[] downloadDataResult = e.Result;

    //eventual exception
    Exception ex = e.Error;

    Console.WriteLine("Downloaded {0:N1}KB", downloadDataResult.Length / 1024d);
}

The same features are available in any of our classes by implementing the same pattern. Here is an example:

    class Program
    {
        static void Main(string[] args)
        {
            var instance = new SimpleAsyncClass();

            Console.WriteLine("Sync value: {0}", instance.ProcessSomething());

            //register an event handler to catch the result
            instance.ProcessSomethingCompleted += instance_ProcessSomethingCompleted;
            //invoke async invoke
            instance.ProcessSomethingAsync();

            Console.WriteLine("MAIN THREAD ENDED");
            Console.ReadLine();
        }

        static void instance_ProcessSomethingCompleted(object sender, int e)
        {
            Console.WriteLine("Async value: {0}", e);
        }
    }

    public class SimpleAsyncClass
    {
        public int ProcessSomething()
        {
            Thread.Sleep(3000);
            //returns a random integer
            return DateTime.Now.Millisecond;
        }

        public void ProcessSomethingAsync()
        {
            //initialize a delegate object to make async call
            var invoker = new Func<int>(ProcessSomething);
            //start async elaboration with callback
            invoker.BeginInvoke(InnerProcessSomethingCompleted, invoker);
        }

        private void InnerProcessSomethingCompleted(IAsyncResult ar)
        {
            //catch the delegate object from async state
            var invoker = (Func<int>)ar.AsyncState;
            //raise the event with computed value
            if (ProcessSomethingCompleted != null)
                ProcessSomethingCompleted(this, invoker.EndInvoke(ar));
        }

        //the event that is usable for intercepting the computed value
        public event EventHandler<int> ProcessSomethingCompleted;
    }

This simple implementation gives us the ability to understand how EAP works. The pattern asks us to add some naming conventions such as the syntax Async at the end of the method or the syntax Completed for the acknowledgement event.

The pattern itself, in its pure version, is more verbose than how it was just seen. It also requires a specific Delegate declaration for each method (although all with the same sign), cancellation support, process state notification (the percentage or completion), and a busy indicator. It is at the discretion of the programmer whether to implement a pure pattern or a simplified one, as visible in the example just given.

The BackgroundWorker is a component that supports a full EAP with the ability to run in an asynchronous way and synchronize the UI access by itself (discussed later in this chapter in the Task UI synchronization section).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.237.79