Wednesday, 29 October 2014

Simpler Silverlight/C# syntax for async web service calls using delegates

So, I've been using Web-Service calls in Silverlight for a number of years now in a bunch of different applications with the cumbersome async BeginGetResponse, callback, EndGetResponse syntax. It's all been working great, I happily have a template for this and can bash any new service integrations pretty quickly and has not been getting in the way.

For a simple Get request they look something like this:


public string server = "123.123.123.123";


public void GetExample()
{
    String url = "http://" + server + "/getexample";

    try
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

        IAsyncResult result = null;

        result = request.BeginGetResponse(GetExampleCallback, request);
    }
    catch (Exception)
    {
    }
}

void GetExampleCallback(IAsyncResult ar)
{ 
    var request = ar.AsyncState as HttpWebRequest;
    var response = request.EndGetResponse(ar) as HttpWebResponse;

    using (var reader = new StreamReader(response.GetResponseStream()))
    {
        string result = reader.ReadToEnd();

        // now do something with this
    }
}

Which is all good and I usually have some additional code here to callback to a delegate which can then do something, such as display the result asynchronously with the usual fun and games of getting this back onto the GUI thread using a BeginInvoke Dispatch.

Great. It then gets a little more complicated when you want to make a post request and have to push the XML parameters in another asynch BeginGetRequestStream function which means you're getting callback after callback. Easy enough, these can be bundled into a class for each WebService function and can use some templating to reduce the effort, but it's still pretty tedious. I've stuck with it because it works, I have a pattern and usually it's not too much trouble and once done means I can focus on the other interesting bits of the application.

Just this week though I needed to make a new little application and having some brain-space to look at this again and thinking Swift closures I thought I'd explore a bit how to get rid of the callbacks explicitly in the calls and see if this could be made into a single function. Sort-of and there are pros and cons.

What I came up with looks like this:

using System.Threading.Tasks;

public string server = "123.123.123.123";


public void GetExample2()
{
    String url = "http://" + server + "/getexample2";


    try
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

        IAsyncResult result = null;
        ManualResetEvent mre = new ManualResetEvent(false);

        result = request.BeginGetResponse((cb) =>
        {
            // Callback
            using (var response = request.EndGetResponse(cb) as HttpWebResponse)
            {
                using (var reader = new StreamReader(response.GetResponseStream()))
                {
                }
            }

            mre.Set();

        }, request);


        mre.WaitOne();
    }
    catch (Exception)
    {
    }
}


In this case the callback has been put in as an anonymous delegate so the code can be written in the same function. Now what is all the ManualResetEvent stuff about? Basically this is to handle the aynchronous nature. If you run this in the debugger you can see the BeginGetResponse call being made and then jumping down to mre.WaitOne() which is the normal thread flow of the operation. You can then see the debugger jump back up to the callback. The mre.Set then sets the flow to continue in the main thread once the callback has finished.

So, pros and cons.

The big pro is that the whole operation is now contained in a single function statement and local variables can be used to return the result. You can either make this synchronous now (as the synchronicity has been put into the call with the ManualResetEvent) or callback via a delegate (recommended) with the result.

The con is that there are seemingly multiple code execution entries in a single statement. Remember all those gotos and horrible code years ago. Well, lots of coding best practice is to make code more readable and the execution paths clearer and more understandable. [See also later note on calling from the GUI thread]

The nub of the question is if this is easier to read and understand and means there will be fewer problems. I kind of think so as once the template/pattern is established it's much easier to put together and therefore for me less prone to errors.

The big advantage now is if you need to do a Post, it looks sort of like this:


public void PostExample()
{
    String url = "http://" + server + "/postexample";


    try
    {
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        request.AllowReadStreamBuffering = false;
        request.Method = "POST";
        request.ContentType = "text/xml";


        IAsyncResult result = null;
        ManualResetEvent mre = new ManualResetEvent(false);


        result = request.BeginGetRequestStream((ac) =>
        {
            // post request callback
            using (Stream stream = request.EndGetRequestStream(ac))
            {

                StreamWriter writer = new StreamWriter(stream);


                string post = "";

                post += "<?xml version='1.0' encoding='UTF-8'?>";
                post += "<somexml/>";

                writer.Write(post);

                writer.Flush();
                writer.Close();
            }

            mre.Set();

        }, null);

        mre.WaitOne();
        mre = new ManualResetEvent(false);

        string reply = "";

        result = request.BeginGetResponse((cb) =>
        {
            // callback response
            var response = request.EndGetResponse(cb) as HttpWebResponse;

            using (var reader = new StreamReader(response.GetResponseStream()))
            {
                reply = reader.ReadToEnd();
            }

            mre.Set();

        }, request);

        // this needs to stay in for some strange reason
        Thread.Sleep(100);

        mre.WaitOne();
    }
    catch (Exception)
    {
    }
}

Which is pretty great.

Now, the additional funny. I don't like the Sleep at the end, but however I tried to work this out, I could not get things to work and the last wait just waited on for ever, so pragmatically it is working for me but is an ugly little hack.

Second thing to note with this method is that these functions cannot be called from the GUI thread directly as the callback in BeginGetResponse never comes back. That caused me a lot of headaches until I found the result. In the case of my application this is not a problem as all the service calls are running from a separate thread and updating the GUI. Still, it's messy. There are ways around this similar to the Dispatch back the other way, but it's not completely clean.

I did mess around with the new C# async keyword and using the task framework but the code really looked ugly to my eyes. Maybe a little more work on that and another post in the future.

Friday, 17 October 2014

Silverlight Multi-Select User Control

So back to some Silverlight fun. I had a requirement for some applications I was putting together to have a multi-select drop-down that allowed typing in and selection from a list of available values. I'm sure there was some code around but I took a quick look and this didn't jump out at me immediately so I had a bit of an evening code. Here's the results. Please do take yourself and improve, please drop me a comment on this blog if you find it useful or use it for anything.

There's a demo below... try typing into the box. The version used below does not allow duplicates. This is an option in the user control.


The code files are available below:
The code is a little klunky in places and could certainly be improved. I'll try to get round to that when I have some spare time. However, it met the need that I had at the time. 

There are a number of areas for improvement, putting in disable functionality and allowing different colours for the selected items. 

There are a couple of little tricks that are worth calling out...

In a couple of places I needed to send a message to a control to get it to have a visual interaction. The easiest way I found for doing this was to use a lambda to drop it onto the dispatcher:

Dispatcher.BeginInvoke(() => options.Visibility = Visibility.Collapsed);

These are paths for the right and down arrow:

<Path x:Name="arrowright" VerticalAlignment="Center" Margin="0" Stroke="Gray" 
      Data="M2,8 L6,4 L2,0"  StrokeThickness="2"/>
<Path x:Name="arrowdown" VerticalAlignment="Center" Margin="0" Stroke="Gray" 
      Data="M8,0 L4,4 L0,0"  StrokeThickness="2" Visibility="Collapsed"/>

And this is the path for the cross symbol used in the buttons:

<Path VerticalAlignment="Center" Margin="3" Stroke="Gray" Data="M0,0 L8,8 M8,0 L0,8"  StrokeThickness="2"/>

Thursday, 16 October 2014

Polifiller and Buzzword Bingo

Caught this on Radio4's Today programme driving in this morning (quote from the Beeb)...

"A new online tool, Polifiller.com, is being launched, which will supposedly automatically strip jargon and clichés out of politicians' speeches and statements - to help politicians rid their vocabulary of hackneyed phrases and give the electorate the clarity they deserve. Hamish Thompson, managing director of Houston PR developing the online tool and Robert Hutton is the UK Political Correspondent for Bloomberg News and author of 'Would They Lie To You? How To Spin Friends and Manipulate People'."

Love the idea!!

At work to keep management on their toes we always have a good round of buzzword bingo at the annual comms sessions. Which made me think, there's a ripe opportunity here for a PPT parser that takes in techno/biz-speak babble and either strikes it out or replaces it randomly with something else....  now if I have a spare evening, that might just appeal