Home  /  Questions  /  Question



60   95.3
Aug 12, 2011


Asynchronous SOA calls

I'm enjoying studying your Patterns In Architecture framework.  Currently, I am particularly interested in setting up asynchronous communication over a SOA interface.  We are building a GUI with many desktops, each containing many windows, each of which can show views of data retrieved from a decoded message-file.  Each window shall retrieve its data seperately over a SOA interface, which hopefully will end up being small and usable like your IActionService interface.  In our very data-intensive system, no request for data may block as this would make the GUI unresponsive.

In your framework you use the Request-Response SOA messaging pattern, it works perfectly and is easy to understand.
Would you care to advise as to how your IActionService interface might look if you needed to make your calls asynchronous?

var response = Client.GetCustomers(request);
are the type of calls that I'm referring to.

Also: do you recommend the book SOA Design Patterns by Thomas Erl
, or can you recommend any other good books that would provide up-to-date advice?

Regards,
Mark




108   96.7
Aug 19, 2011
Below is some code that shows a rudimentary solution. It works in a console application, for a true UI you will need do do more, e.g. marshal the callback event to the UI thread.

The attached "SoaAsync.zip" file also contains a quick WPF application.

class ClientArgs : EventArgs
    {
        public Reply Reply { get; set; }
    }

    class Request
    {
        public string Input;
    }

    class Reply
    {
        public string Output;
    }

    class Client
    {
        public delegate void CallCompletedDel(object sender, ClientArgs args);

        public event CallCompletedDel CallCompletedEvent;

        public void RequestAsync(Request req)
        {
            if( null != CallCompletedEvent)
            {
                ClientArgs args = new ClientArgs();
                args.Reply = new Reply();
                args.Reply.Output = req.Input + " Output";

                // this will actually go to the Web Services as an async call
                CallCompletedEvent.BeginInvoke(this, args, null, null);  
            }
        }
    }

then you uses it in the following way

            ManualResetEvent block = new ManualResetEvent(false);
            bool _isAsyncDone = false;
            Reply reply = null;
            int _timeout = 1000;

            Client client = new Client();
            
            client.CallCompletedEvent += (sender, e) =>
            {
                if( null != e)
                {
                    reply = e.Reply;
                    _isAsyncDone = true; 
                    block.Set(); 
                }
            };


            Request req = new Request();
            req.Input = "Input";
            client.RequestAsync(req);

            block.WaitOne(_timeout, false);

            if (false == _isAsyncDone)
            {
                Console.WriteLine("Test took too long");
            }
            else
            {
                Console.WriteLine(reply != null ? reply.Output : "Reply is null");
            }