Welcome

You have reached the blog of Keith Elder. Thank you for visiting! Feel free to click the twitter icon to the right and follow me on twitter.

Calling Multiple Web Services Asynchronously

Posted by Keith Elder | Posted in .Net, Asp.Net, Programming, Smart Clients | Posted on 16-03-2006

4

There are two ways to call web services:  synchronously and asynchronously.  Below is an example of a syncronous web call.  The HelloWorld() call will not get executed until the ReturnLastCustomer() is completed.  In some cases this is fine.  For example if you need the information from ReturnLastCustomer() to then call the HelloWorld() example.

Syncronous Web Service Call

            localhost.Service proxy = new WindowsApplication3.localhost.Service();

            localhost.MyCustomObject myObject = proxy.ReturnCustomObject();

 

            // Make another call to web service

            string hello =  proxy.HelloWorld();

In the example above we wouldn’t really care if one method completed before another.  There may be code below it that can go ahead and get started processing.  To do this we change this to call the service asynchronously.  The idea behind the asynchronous call is we setup an event that gets notified through a delegate that the web service method is done with processing.  Here is how the synchronous example above would look called asynchronously.  It may look like a little more code, but in Visual Studio as you type this just press tab when it gives you a tooltip help and it will generate the right side of the += as well as the method stub for the call back.

Asyncronous Web Service Call

      public Form1()

        {

            InitializeComponent();

 

            localhost.Service proxy = new WindowsApplication3.localhost.Service();

            proxy.ReturnLastCustomerCompleted += new WindowsApplication3.localhost.ReturnLastCustomerCompletedEventHandler(proxy_ReturnLastCustomerCompleted);

            proxy.ReturnLastCustomerAsync();

 

            // Make another call to web service

            proxy.HelloWorldCompleted += new WindowsApplication3.localhost.HelloWorldCompletedEventHandler(proxy_HelloWorldCompleted);

            proxy.HelloWorldAsync();

        }

 

        void proxy_HelloWorldCompleted(object sender, WindowsApplication3.localhost.HelloWorldCompletedEventArgs e)

        {

            string hello = e.Result;

        }

 

        void proxy_ReturnLastCustomerCompleted(object sender, WindowsApplication3.localhost.ReturnLastCustomerCompletedEventArgs e)

        {

            localhost.MyCustomObject myObject = e.Result;

        }

The Problem

The problem with the above example is depending on the speed of how things get processed we will get random errors that an asynchronous call is currently being processed.  The good news is there is an easy way to address this in .Net 2.0.   There are two overrides for the Async calls.  The first one is it takes the parameters of your web service call.  The second override adds another parameter of type “object userState”.  This allows us to pass in a unique identifier of the call. 

To make sure our asynchronous example above works we need to make sure these calls can run at the same time.  It is a simple change and that would look like this:

Calling Two Asynchronous Calls At the Same Time

            localhost.Service proxy = new WindowsApplication3.localhost.Service();

            proxy.ReturnLastCustomerCompleted += new WindowsApplication3.localhost.ReturnLastCustomerCompletedEventHandler(proxy_ReturnLastCustomerCompleted);

            proxy.ReturnLastCustomerAsync(Guid.NewGuid());

 

            // Make another call to web service

            proxy.HelloWorldCompleted += new WindowsApplication3.localhost.HelloWorldCompletedEventHandler(proxy_HelloWorldCompleted);

            proxy.HelloWorldAsync(Guid.NewGuid());

Notice the only difference in how we call the methods is we generate a new Guid as our userState object.  This allows the calls to keep track of the state of each call.  Pretty easy problem to get around but if you don’t explore your overrides of method calls, you may have missed this one.  Being able to call multiple web service methods asynchronously at the same time is pretty important when writing a Smart Client so you’ll probably use this more in this scenario. With larger Smart Clients you typically have things running in the background to check on statuses, update queues, as well as carry calls to save and return data.  This is how you get around that.

Channel 10 launched

Posted by Keith Elder | Posted in .Net, Internet | Posted on 13-03-2006

0

Channel 9 has been around awhile and is one of the things I spend time in the evening watching if there are new videos.  There’s always good content on channel 9 and its great to hear the people that built a lot of the technology we use talk about it.  Channel 9 is where they interview developers at Microsoft on how things were written or work.  Channel 10 is a new site built upon Asp.Net 2.0, SQL Server 2005 and Ajax.  The site’s mission is to provide content for the other side, the people that are using the technology.  There are lots of cool features in the site.  The team spent a lot of time building some very thought provoking UI into the site.  Watch the video on Channel 9 about how the site was built if you are curious.  Anyway, one of their features is you can put their video content inside of your blog.  I thought I would try it and see how it went but I can’t get it to work.  It seems my blogging software strips it out.  Cool idea though.

You can check out the new site  launch at http://on10.net .

 

Sharing Data with Multiple Windows Forms

Posted by Keith Elder | Posted in .Net, Programming, Smart Clients | Posted on 13-03-2006

1

I see this question a lot on forums, discussion boards and mailing lists.  This question is typically asked in various ways.  Here are a few examples:

  • How do I access a varible in form2 from form1?
  • How do I update a textbox field when a user clicks on a button in form1 to form2?
  • How can form1 be updated with data from form2?
  • How can I share data between two different windows forms?

Whatever the question is the underlying problem is still the same, getting something from A to B or B back to A.  For a developer learning .Net and windows form programming the answer to these questions isn’t so obvious.   Let’s take a look at sharing data such as a strong typed DataSet of Customers between two forms.

To start out with let’s look at the code of a newly created windows form:

namespace KeithElder

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

    }

}

As we see code to a windows form is just an object.  That means if we add a variable in this form that we want to share with another form we would have to make it a public variable.  This is usually what developers try to do at first.  Let’s try this approach first and see where it gets us.

namespace KeithElder

{

    public partial class Form1 : Form

    {

  public CustomerDataSet Customers = new CustomerDataSet();

        public Form1()

        {

            InitializeComponent();

        }

    }

}

Above we added a variable called customers that is public.  This means it can be accessed outside of this form.  If we create another form called Form2 though, how do we easily reference Form1?  In other words we need to get the current running instance of Form1 so we can see the Customers public variable.  Here is one way we could do this:

Form1 myForm = Application.OpenForms[“Form1”] as Form1;

 

This will grab the current open form Form1 and assign it to a variable called myForm.  The first problem with this is we are boxing the Form1 object.  This is costly overhead that we want to avoid.  The other problem is, what if the user closed Form1? Or, what if they never opened Form1?  How do we know?  The answer is we could know, but that would cost us a lot of time developing that logic.  All we REALLY want is the Customers data.  We could care less about the form itself.

 

To solve this problem we can easily create a seperate object that both Form1 and Form2 can access.  This allows us to get data from one location and increase our code reuse factor.  You can call the object whatever you want and even put it wherever you want.  I typically seperate these types of classes out into other class library projects.  The reason is I don’t want any of the objects I reference tied to one single interface.  In the example below I am going to call it “Global.cs”.  Here is how that object would look.

 

using System;

using System.Collections.Generic;

using System.Text;

using System.Data;

 

namespace KeithElder

{

    public static class Global

    {

        private static CustomerDataSet _customers = null;

        public static CustomerDataSet Customers

        {

            get

            {

                if (_customers == null)

                {

                    CustomerDataSetTableAdapters.CustomerTableAdapter ta = new DotNetPimps.CustomerDataSetTableAdapters.CustomerTableAdapter();

                    CustomerDataSet.CustomerDataTable dt =  ta.GetData();

                    _customers = new CustomerDataSet();

                    _customers.Customer.Merge(dt);

                }

                return _customers;

            }

        }

    }

}

 

Notice the class is marked public and static.  This means we do not have to instantiate the class to use the class and we can access it publically in our namespace. There are also two static properties for our customers data.  One is private and one is public.  Having a private static variable allows us to check to see if this variable has ever been accessed and if not, go get the new data.  Otherwise it will return the current data.  You can think of this as sort of a Singleton pattern.

 

The last piece of the puzzle is how do we use this in our Form1 and Form2 scenario.  Let’s look at the code for Form1. There isn’t any need to show Form2 since it will be the same.  That’s the beauty of seperating the data out.

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

 

namespace KeithElder

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

 

        private void Form1_Load(object sender, EventArgs e)

        {

            this.customerDataGridView.DataSource = Global.Customers;

            this.customerDataGridView.DataMember = “Customers”;

        }

}

 

On Form_Load we retrieve the customer data and bind that to our DataGridView control.  The same code would apply to Form2.

Tonight is game night

Posted by Keith Elder | Posted in Friends, Funny Stuff | Posted on 12-03-2006

0

A few weeks ago Ellen and I had to go to Jackson for the weekend to a piano contest she was judging. Since we had to leave for two nights we needed someone to watch our dogs while we were away. Two of Ellen’s students, Carlena and Shea, agreed to watch the dogs for us but we had to have game night at our house to reward their services. Tonight was game night. Everyone gets together and we have a meal then we break out all of the board games. We started by cooking some burgers and hot dogs on the grill and then played a few hands of Texas Hold ‘Em since they girls had never played. Then another student of Ellen’s named Nathan showed up and we started playing Mad Gab and then moved onto Taboo. The night is still young, who knows what we’ll break out next. Maybe Operation?

Page Methods and URL rewriting

Posted by Keith Elder | Posted in Asp.Net, Programming | Posted on 11-03-2006

0

Although I haven’t used this particular project, I ran across something today that I thought was an interesting project.  The project allows you to handle page methods and rewrite URLs.  For example if you have a URL like keithelder.net/blog/article.aspx?id=12 and you want it to be keithelder.net/my-title.aspx instead.  Virtual URLs are very handy.  Even on blogs like this for example where you link to a post of a item, you aren’t really hitting a static page.  It is all virtual. 

The project just released an update for VS2005. You can check it out on the offical PageMethods web site.