I’ve just been following Philippe’s tutorial on creating a cloud based WCF service and consuming it from a client application. I happened to have just installed Visual Studio 2012 and the Azure SDK, so I decided to use that instead of my trusty old Visual Studio/.NET 4.0 installation.
Following Philippe’s tutorial, I noticed some extra buttons when configuring my client’s service reference:
After doing a bit of digging, I realized that this could be used with the .NET Framework 4.5 async and await keywords, which I’d read about recently. I implemented my WCF Service on Azure using the C# ‘Windows Azure Cloud Service’ project type, and selecting the ‘WCF Service Web Role’:
I actually followed Microsoft’s tutorial to create the service, rather than Philippe’s instructions because I was going straight to Azure and not AWS (sorry Philippe ).
My service implementation looks like this:
public class Service1 : IService1
{
public string GetHello1()
{
return "Hi there!";
}
public string GetHello2()
{
Thread.Sleep(5000);
return "Yo!";
}
}
Note the deliberate delay in GetHello2(). And my simple contract looks like this:
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetHello1();
[OperationContract]
string GetHello2();
}
My test client was a simple Windows Forms application. I added two service references to it – one with the settings Philippe describes in his tutorial (and that the MS tutorial also uses), the other using the settings in the screenshot above.
The equivalent code to Philippe’s (the ‘old’ way) is:
//Asynchronous using callbacks
private void button2_Click(object sender, EventArgs e)
{
client1 = new ServiceReference1.Service1Client();
client1.BeginGetHello1(new GetHello1Request(),
new AsyncCallback(MyAsyncResponder), null);
}
private void MyAsyncResponder(IAsyncResult result)
{
try
{
GetHello1Response response = client1.EndGetHello1(result);
if (result.IsCompleted)
{
//Have to make sure we access form from correct thread
this.Invoke(
new UpdateFormDelegate(UpdateForm),
new object[] { response.GetHello1Result });
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
client1.Close();
}
}
private void UpdateForm(string txt)
{
label1.Text = txt;
}
private delegate void UpdateFormDelegate(string txt);
Those callbacks and delegates are a bit of a pain for me. They really break up the flow of the code when I’m reading it. Which is why I was so happy when I worked out how to do the same thing using async/await (the ‘new’ way):
//Asynchronous using await/async keywords
private async void button3_Click(object sender, EventArgs e)
{
try
{
client2 = new ServiceReference2.Service1Client();
string res = await client2.GetHello2Async();
//Control now returns back to the form until above
// call returns
//Clicking other buttons while you're waiting invokes their
// code handlers.
//When call returns the next line is invoked
label1.Text = res;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
client2.Close();
}
}
The comments explain what happens with the flow of the code. It’s a kind of magic!
[Health warning: This is my first time creating a WCF web service and client, and my first time using await/async – so don’t assume my coding is optimal. I was just so excited about async/await that I had to blog about it ]
PS: Yes – I know my exception handling is incomplete.
Comments