CRM Development

Solutionist has designed the architecture for a new CRM system for use in the medical imaging industry.

Monday, 16 July 2012

Asynchronous WCF using the generated service interface

Using Asynchronous WCF in an IoC style presents an interesting challenge.


Normal examples show that you can call async WCF something like this...
      Service1Client iService1 = new Service1Client();
      iService1.GetDataCompleted += iService1_GetDataCompleted;
      iService1.GetDataAsync();



i.e. you declare the service client implementation, specify the callback and make the async call.


But... what if you want to inject the client reference, for example (using Ninject):
[Inject]
IService1 iService1 {get; set;}

where Service1 is the interface.
Well, you find that the xxxCompleted event and xxxAsync method are not available on the interface. Ouch!
But, all is not lost...
You do have two other methods... Beginxxxx and Endxxxx and you can use them as in the example below. In the Beginxxxx method you specify the callback and in the callback you can get hold of the result by calling Endxxxx


Note that in the example below, I haven't injected the Service client, but I am using the interface, IService1. The code produces the following output (with the "Waited" appearing after the calling thread has slept for 5 seconds) :

    Making call
   Got result
   You entered: 200
   Waited

    public class Program
    {
        private static void Main(string[] args)
        {
            MakeAsynchronousCall(200);
        }
 
        private static void MakeAsynchronousCall(int value)
        {
            IService1 iService1 = new Service1Client();
 
            AsyncCallback aSyncCallBack =
                delegate(IAsyncResult result)
                    {
                        try
                        {
                            Console.WriteLine("Got result");
                            var i = iService1.EndGetData(result);
 
                            Console.WriteLine(i);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                    };
 
            try
            {
                Console.WriteLine("Making call");
                iService1.BeginGetData(value, aSyncCallBack, iService1);
 
                Thread.Sleep(5000);
 
                Console.WriteLine("Waited");
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }

The Server-side code is :
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }