Re.Mark

My Life As A Blog

Multithreading with the .NET Compact Framework 3.5

with 8 comments

Discussing the user experience of the mobile application during the National Rail Enquiries Proof of Concept, it was clear that the departure and arrival times for trains should appear on the same screen.  At the time of writing, there is one webservice call to get the list of trains (with departure times) and another call, one for each train, to get the arrival details – and a list of all the stations the train will call at.  to get the code working, I started out with one thread.  As expected, this approach led to a slow, unresponsive screen.  Multithreading was an obvious answer.  Having done a little research into multithreading with the .NET Compact Framework 3.5, I set about updating the screen.  Here is what I learned.

Multithreading with WinForms

The approach I’ve taken in the past to multithreading with WinForms is to use the BeginInvoke method of a delegate to call a method, handle the result of the method with an asynchronous callback and raise an event for which the form has an event handler.  This way there’s no attempt to modify the UI with a background thread.  In this instance, it would mean one thread per train, but there’s no thread specific code.

Capabilities of the .NET Compact Framework

The BeginInvoke method of a delegate is not supported within the .NET Compact Framework 3.5.  There is a BeginInvoke method on the Control class (of which Form is a descendant) that runs asynchronously, but it runs on the UI thread.  For multithreaded programming, there are two obvious options: spin up new threads with Thread.Start or using ThreadPool.QueueUserWorkItemThread.Start in WinForms has an overload that allows you to pass an object as a parameter.  There is no such overload in the .NET Compact Framework.  If you do use this method, setting the IsBackground property to true seems like a good idea.  ThreadPool.QueueUserWorkItem takes two arguments: a WaitCallback, which is a delegate to a method to be called, and an object containing state.  There is also a static method DoEvents on Application which “all Windows messages currently in the message queue” (more info here), which essentially means that it gives your form a chance to catch up.

A multithreaded design for the mobile application

Armed with this information, I was ready to move to a new design.  There’s a form that, in the OnLoad event, gets the trains from a given station to a given station.  This list is bound to a datagrid.  At this point a new thread is created, set to be a background thread and started off.  Here’s a snippet of the code:

Thread thread = new Thread(GetArrivalTimes);
thread.IsBackground = true;
thread.Start();

That background thread will call a method called GetArrivalTimes.  The simplest design is to have one thread for the whole list, that was a bit slow.  The second simplest design was to have one thread per train in the list.  That seemed to overload my mobile.  I ended up with a method that could use a configurable number of threads.  It divides the list of trains so that each thread has its own list to process.  Here’s the code:


const int THREADS = 2;

List<ServiceInformation>[] controlList =

    (List<ServiceInformation>[])Array.CreateInstance(typeof(List<ServiceInformation>), THREADS);
for (int j = 0; j < THREADS; j++)
{
    controlList[j] = new List<ServiceInformation>();
}
for (int i = 0; i < serviceData.Count; i += THREADS)
{
    for (int j = 0; j < THREADS; j++)
    {
        if ((i + j) < serviceData.Count)
        {
            ServiceInformation info = serviceData[i + j];
            controlList[j].Add(info);
        }
    }
}
foreach (List<ServiceInformation> list in controlList)
{
    WaitCallback callback = new WaitCallback(ProcessList);
    ThreadPool.QueueUserWorkItem(callback, list);
}

During development, I adjusted the value of the THREADS constant, and two seemed to give the best results.  As you can see from the code, there is a method called ProcessList that gets handed a list of trains to process.  This method gets the arrival information and calling stations.  When it has the information it updates the data (which is a raises an event for which there is an event handler on the form.  When the event is raised, the datagrid is invalidated, which makes it repaint, so the arrival times show as they come in.

Conclusion

It may at first seem daunting to write multithreaded code for the .NET Compact Framework, but most of the techniques you’ve read about and used for WinForms work.  There’s a lot of helpful information in the Windows Mobile Developer Centre, the Windows Mobile Team blog and Daniel Moth’s blog.

Written by remark

October 10, 2008 at 5:09 pm

8 Responses

Subscribe to comments with RSS.

  1. Hi! A good forum, glad to join you :-)

    Axiontili

    January 22, 2009 at 7:08 am

  2. Just the thing I’m looking for… Thanks and kudos to you

    Ronald J

    May 17, 2009 at 4:39 pm

  3. I didn’t understand.

    Jab

    July 20, 2009 at 7:44 am

  4. This looks cool so far, what’s up people?
    If there are any real people here looking to network, leave me a post.
    Oh, and yes I’m a real person LOL.

    Peace,

    RonoByboany

    August 14, 2009 at 4:54 am

  5. Hi everyone just wanted to introduce myself, looks like a great forum.

    ERELADEPGYCLE

    November 27, 2009 at 7:26 am

  6. Do you have the full code somwhere?

    LC

    August 2, 2010 at 6:16 am

  7. Soppresso (mix argomento)

    soulgetle

    February 17, 2012 at 3:56 am

  8. Great article! We will be linking to this great content on our site.
    Keep up the good writing.

    locksmith st kilda east

    January 7, 2013 at 11:50 am


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: