Tag Archives: Threading

Hacking Polar Watch WebSync Software

I recently purchased a Polar FT-40 watch to monitor my fitness level and track my workouts better. I like the watch so far although I’m not ready to give a thorough review on it just yet. Today, I received the Polar FlowLink data transfer unit that allows me to transfer the data on my watch to Polar’s website. It allows you to chart your progress and do all sorts of interesting things with the data. I was surprised how easy and smoothly the software worked. However, I wanted the data on my desktop so I could do more with it. I wanted to provide my own charts and data views in Excel. I wanted to be able to post it to my blog easily or write a WordPress widget to display my data. That said, I decided to look at what the WebSync software was written in. I had a sneaking suspicion that it might be .NET — I was right!

So, I decided to look under the hood and see if I could tackle writing my own front end to their devices. What I found should horrify anyone who has ever read past Chapter 1 of a reasonable “C#” book.

I started by pulling in the obvious assemblies to see what was built. The project looked reasonably well built. There was enough evidence ot see that there was at least SOME design put into the application. I even found some tests in tone assembly — at least there were some tests (checked that off on their requirements eh?). When I took a look at the EXE, however, what I saw shocked me. So I started drilling down into WebSync.exe. I found a Polar.WebSync.Program class with a static Main() method. Bingo – my entry point. I immediately saw some minor concerns. For instance, they were using a Mutex to provide the functionality of a Singleton pattern. Worse yet, they were calling GC.KeepAlive() on the Mutex. Interesting. They did, however, have what looked like an external exception reporting framework, so that at least gave me SOME hope.

I found Application.Run that was starting a new WebSyncTrayForm() so I naturally followed to the form constructor. In a big Try/Catch block (with no code executing in the “catch” portion), I found a TextBox-style TraceListener was added to the form — mmkay. That’s a decent idea I suppose, but let’s look at the form’s Load event. Oh my! I closed my eyes and looked again. I closed then and then looked one more time. Oh, these folks must have written some VB code with “DoEvents” called more than a few times in their past history. Tell me what you see wrong with this:

WARNING: Not good example code!!

private void WebSyncTrayForm_Load(object sender, EventArgs e)
{
    base.Visible = false;
    this.notifyIcon.Tag = this.notifyIcon.Icon;
    this.toolTip = this.notifyIcon.Text;
    this.notifyIcon.Text = this.toolTip + "n" +
        Resources.StatusInitializing;
    this.timerDaemon = new Timer();
    this.timerDaemon.Interval = 0x2710;
    this.timerDaemon.Tick += new EventHandler(this.timerDaemon_Tick);
    this.timerDaemon.Start();
    this.timerDaemon_Tick(this.timerDaemon, EventArgs.Empty);
}

Seriously? These guys set up a timer, and then start it, and then MANUALLY call the Tick function they just set up! (how do they know it hasn’t been executed already between the start call and a thread interuption that might have caused the Tick event to get executed next.

Then I looked at the tick event and I couldn’t believe what I was seeing.

WARNING: Not good example code!!

private void timerDaemon_Tick(object sender, EventArgs e)
{
    this.retryCount++;
    try
    {
        if (this.retryCount == 6)
        {
            this.timerDaemon.Interval = 0xea60;
        }
        this.mounter = new WristUnitListener();
        this.mounter.WristUnitMounted +=
                new WristUnitConnectionEventHandler(this.WristUnitMounted);
        this.mounter.WristUnitUnmounted +=
                new WristUnitConnectionEventHandler(this.WristUnitUnmounted);
        this.mounter.Start();
        this.DoInitialConfig(null);
        this.timerDaemon.Stop();
        this.timerDaemon.Dispose();
        this.timerDaemon = null;
        this.notifyIcon.Icon = this.notifyIcon.Tag as Icon;
        this.notifyIcon.Text = this.toolTip + "n"
                + Resources.StatusRunning;
        Trace.WriteLine("Connected to Polar Daemon.", "WebSync");
    }
    catch (ConnectionException exception)
    {
        if (this.retryCount < 6)
        {
            Trace.WriteLine(
               string.Format("Couldn't connect to Polar Daemon ({0})",
                              exception.CodeString),
                             "WebSync");
        }
        if (this.retryCount == 6)
        {
            Trace.WriteLine(
               string.Format("Couldn't connect to Polar Daemon ({0})",
                             exception.CodeString),
                             "WebSync");
            Trace.WriteLine(
               string.Format("WebSync couldn't initialize properly." +
                             "Please check that Polar Daemon service is running.",
                              new object[0]), "WebSync");
            this.notifyIcon.Icon = Resources.IconExclamation;
            this.notifyIcon.Text = this.toolTip + "n" + Resources.StatusInitError;
            this.notifyIcon.ShowBalloonTip(0x2710, Resources.ToolTipProblemTitle,
                              Resources.ToolTipInitError, ToolTipIcon.Warning);
            this.notifyIcon.BalloonTipClicked +=
                new EventHandler(this.notifyIcon_BalloonTipClicked);
        }
    }
}

OK. These guys are on crack! They have a retry counter that apparently will never be more than 1. Because the tick event will go away and there is no loop in this code, the retryCount will always be 1 (taking note that they decided to start with a 1-based counting system rather than zero because n-1 is a bit complex). That at didn’t stop them from checking to see if it was equal to 6, and if so, changing the interval.

In the tick event, they create a new instance of a WristUnitListener and hook up events to it EACH time. They call start on the WristUnitListener instance and then STOP the timer and dispose of it! Never mind the fact that this timer execution is owned by the main thread rather than the timer tick function — when a timer stops itself, disposes of itself, and then nulls itself, it’s time to reevaluate your understanding of background-thread polling. This is insane! I have no idea how this even works. I can only hope that, as I dig in further WristUnitListener actually works the way it is supposed to and the only thing that sucks is the WebForms code.

Update January 13th, 2010 1:15AM PST:

I was able to successfully hack around with the API and get data off the watch with little effort. The trick was to working around some wonky and non-working APIs. To their defense 1) this API and software has to work with multiple watches 2) wasn’t intended to be consumed by other devs 3) was written with interop for the native libraries accessing the hardware, 4) does show signs of some intelligent thinking (although does need considerable amounts of re-work). As you can see by the image, I can even pull the bitmap logo off of the watch and, if I so desire, set it.

This is far from complete but I will work it over some this week and this weekend before publishing the source on Codeplex. Let me know if there is something in particular that you’d like to see.

 

Update July 7th, 2010 12:01AM PST:

I have posted this code to codeplex as-is. You can find it here: http://polarsync.codeplex.com/

If you would like to contribute source code or improve the project for others in the community, please send me a request and I’ll approve you. I don’t intend to maintain the code or improve it.

Unsafe thread safety

As I stated in my last post, for the past two days I’ve been sitting in Jeffrey Richter’s threading class. The class is near the end and I can’t say that a lot of new concepts have been taught. Another student and I have decided that the class should have been renamed, “Threading Basics”. That’s not to say anything of Richter’s teaching skill or the content of the class.  It just goes to show that if the architecture of a product is right, the threading code should be extremely simple to use.

However, what I love about this class is that it reminds me how much I enjoy this topic.  The theory of the perfect architecture doesn’t exist. Additionally, many times the developer has little-to-no ability to push back on a bad architecture. It’s in these cases that you must use your bag of concurrency tricks to work out of the whole the architect(s) put you in.  That sound easy enough, but what if the architecture included – *gasp* – “less-than-optimal” decisions in the actual .NET framework classes?  What if those decisions were made in the very methods that are supposed to help you with these synchronization problems?  These problems perplexed me when I first encountered them and I never really thought to blog about them (I was actually just scared I was doing something wrong).  Taking this class gave me the perfect excuse to bring the topic up.

Take a look at the following pattern in C++:

class CConcurrencySample
{
public:
    CConcurrencySample( ) 
    {   // Initialize a critical section on class construction
        InitializeCriticalSection( &m_criticalSection );
    };
    ~CConcurrencySample( ) 
    {   // Destroy the critical section on class destruction
        DeleteCriticalSection( &m_criticalSection );
    };

    // This method is over-simplified on purpose
    ////////////////////////////////////////////////////////////
    BOOL SafeMethod( )
    {
        // Claim ownership of the critical section
        if( ! TryEnterCriticalSection( &m_criticalSection ) )
        {
            return FALSE; 
        }

        ////////////////////////////////////////////////
        // Thread-safe code goes here
        ////////////////////////////////////////////////

        // Release ownership of the critical section
        LeaveCriticalSection( &m_criticalSection );

        return TRUE;
    };
private:
    CRITICAL_SECTION m_criticalSection;
};

Anyone that’s done any work in threading recognizes this pattern. We’ve declared a class named CConcurrencySample. When any code instantiates an instance of CConcurrencySample, the constructor initializes the private CRITICAL_SECTION instance in the object. When any code destroys an instance of CConcurrencySample, the CRITICAL_SECTION is also deleted. With this pattern, we know that all members have access to the critical section and can claim ownership of the critical section at any point. For my purposes, I’ve created a method named SafeMethod that will take the critical section lock when it is called, and release the lock when it leaves the method. The good part about this pattern is that each instance has a way to lock SafeMethod. The downside is that if client doesn’t need to call SafeMethod, then the CRITICAL_SECTION is created, initialized and destroyed without need — uselessly taking up memory (24 bytes on a 32bit OS) and processor cycles.

The CLR implemented this pattern and even expanded on it. They also tried to fix the waste incurred with non-use of the critical section. The CLR implementation works as follows. Each System.Object created by the CLR contains a sync block index (4 bytes on a 32bit OS) that is defaulted to -1. If a critical section is entered within the object, the CLR adds the object’s sync block to an array and sets the object’s sync block index to the position in the array. With me so far? So how does one enter a critical section in .NET? Using the Monitor class, of course. The following example emulates the same functionality as the previous C++ sample by using C#.

public class CConcurrencySample
{
   bool SafeMethod( )
   {
      // Claim ownership of the critical section
      if( Monitor.TryEnter( this ) )
      {
          return false;
      }

      ////////////////////////////////////////////////
      // Thread-safe code goes here
      ////////////////////////////////////////////////
    		
      // Release ownership of the critical section
      Monitor.Exit( this );

      return true;
    }
}

Monitor.Enter and Monitor.Exit are supposed to provide similar functionality of entering and leaving a critical section (respectively). Since all System.Object’s have their own SyncBlock, we just need to pass our current object to the Monitor.Enter and Monitor.Exit method. This performs the lock I described earlier by setting the sync block index. Sounds great, but what’s the difference between that C++ example and the C# pattern? What issue can you see in the .NET framework implementation of this pattern that you don’t see in the C++ sample I provided?

Give up?

The answer simple. In the C++ sample, the lock object (the CRITICAL_SECTION field) is private. This means that no external clients can lock my object. My object controls the locks. In the .NET implementation, Monitor.Enter can take ANY object. ANY caller can lock on ANY object. External clients locking on your object’s SyncBlock can cause a deadlock.

    public class CConcurrencySample2
    {
        private Object m_lock = null;

        bool SafeMethod ( )
        {
            if ( m_lock == null )
            {
                m_lock = new Object( );
            }
            if ( ! Monitor.TryEnter( m_lock ) )
            {
                return false;
            }

            ////////////////////////////////////////////////
            // Thread-safe code goes here
            ////////////////////////////////////////////////

            Monitor.Exit( m_lock );

            return true;
        }
    }

With this approach, we are declaring an plain, privately-declared object in the class. Be careful when using this approach that you don’t use a value-type for your private lock. Value type’s passed to a Monitor will be boxed each time the methods on Monitor is called and a new SyncBlock is used — effectively making the lock useless.

So what does this have to do with IIS? Nothing just yet. But I plan to cover some asynchronous web execution patterns in future posts and I figured this would be a great place to start.

This information is pretty old but sitting in class I realized it might not be completely obvious to everyone just yet. If you were someone in-the-know about this information since WAY back in 2002, please forgive the repitition.

Threading issue with VB.NET Default Instances

Here is an issue that showed up for one of our customers in the Microsoft forums for Visual Basic .NET.  It is NOT the typical ”cross-threaded UI update” issue that you might think. No, this one, IMO, is slightly harder to catch since no exception is thrown to let you know something has gone wrong.

One of the many new features of Visual Basic .NET are default form instances.  As the feature lists explain, a default form instance prevents you from having to “new up” an instance of a form before acting on it.  So, instead of using:

Dim frm As New frmMain
frm.Show()

I can simply use:

frmMain.Show()

This is handy, particularly for the folks coming from VB6 who are used to forms that behave in this manner.  However, default instances present a very interesting problem.

Take, for instance, a project that I create with a form (named frmMain) and a module (named BackgroundMethods.vb) .  For the form, I have simply added a multi-line text box (named txtOutput) and a button control (named button1). 

Here is the code I have in my project:

[frmMain]

Imports System.Threading
Public Class frmMain
  Private Sub Button1_Click( ByVal sender As System.Object, _
                             ByVal e As System.EventArgs) _
                             Handles Button1.Click
     Dim t As Thread = New Thread(AddressOf GetData)
     t.Start()
     txtOutput.Text &= "Updates complete"
     ' Break after the call above to read the value
     ' in txtOutput.Text
  End Sub
End Class

[BackgroundMethods.vb]

Imports System.Threading
Module BackgroundMethods
   Public Sub GetData()
      WaitForData("Message 1")
      WaitForData("Message 2")
   End Sub
   Public Sub WaitForData(ByVal strMessage As String)
      ' Presumably this method would actually be
      ' waiting for data from a network connection,<
      ' serial port, or other source
      Thread.Sleep(2000)
      My.Forms.frmMain.txtOutput.Text &= (vbCrLf & Now().ToShortTimeString() & _
      vbTab & strMessage)
      ' Break after the call above to read the value
      ' in My.Forms.frmMain.txtOutput.Text
   End Sub
End Module

So the simple example is that I have a button which, when clicked, will execute the “GetData” method asynchronously in a module.  That method is going to call the WaitForData method that updates the UI with two different messages (“message1” and “message2”).  WaitForData is supposed to simulate a long-running process, so I threw in the typical “thread.sleep” call to make this illusion. 

If you run this code, you will notice that no exceptions are thrown, but the UI for your form is also not updated.  Why is this?  You would have at least expected a cross-thread exception, right?

In any other managed language, this likely wouldn’t happen — namely because the “My” application is specific to VB, as well as default form instances!  In C#, if I try to update the UI from another thread, I would get an exception stating: “Cross-thread operation not valid: Control ‘txtSerialIn’ accessed from a thread other than the thread it was created on.” which could be solved by using the “Invoke” method.   

The issue with Visual Basic, in this instance, is that the default form instances are thread-specific.  So, when I try to access the form using My.Forms.frmMain from within the worker thread, a NEW default instance is created under the covers.  My calls to update the text box are then executed on the NEW instance of the form which resides in the same thread as the call to update it — hence it doesn’t throw a cross-thread exception. In the mind of the VB program, the request to update the textbox occurred without an error.  When the worker thread dies, the second instance of the form (which was never displayed) is now a candidate for garbage collection.  Meanwhile, back on the original thread and original form the textbox is left blank.  You can validate this by running the program (I have attached sample code to this blog post) and setting breakpoints on the textbox update line in the WaitForData method, and in the last line of the button1_click event handler of the code.  You will notice that after the second call to WaitForData (before the debugger exits the Sub) that My.Forms.frmMain.txtOutput.Text has been properly set to the value you expected.  However, remember that this is on a second background instance of the form, not the original one you expected.  Once the debugger hits the last line in the button1_click event handler, read the value of txtOutput.Text and realize THAT instance of the textbox was never updated.

So what is the solution?

First off, you still have to use the “Invoke solution” that is often times bandied about in threading discussions.  To do this in VB.NET (and particularly in our solution), do the following:

1. Add the following code to the top of your BackgroundMethods.vb file:

Delegate Sub UpdateTextHandler(ByVal strMessage As String

This allows you to create a delegate that can be invoked on the UI.

2. Add the following method to your frmMain file:

Public Sub UpdateTextMethod(ByVal strMessage As String)
   txtOutput.Text &= (vbCrLf & Now().ToShortTimeString() & vbTab & strMessage)
End Sub

This creates the method that will actually be executed via your delegate from the worker thread.

3. Change your WaitForData method as follows:

Public Sub WaitForData(ByVal strMessage As String)
    ' Presumably this method would actually be
    ' waiting for data from a network connection
    ' serial port, or other source
    Thread.Sleep(2000)
    Dim f As frmMain = My.Application.OpenForms("frmMain")
    f.Invoke(New UpdateTextHandler(AddressOf f.UpdateTextMethod), _
             New Object() {strMessage})
End Sub

This method now uses the form’s “Invoke” method (actually defined in Control) to execute UpdateTextMethod on the original form via the UpdateTextHandler delegate.

So what is happening is that your new thread is getting an instance to the existing frmMain instance by going through the OpenForms call.  Once I have that instance, I can invoke a delegate that points to the “UpdateTextMethod” of the existing form ( passing in the message in the object array ).  By invoking, I am able to get back on the UI’s thread and that call can execute any updates to the UI that it wishes.

Keep this in mind the next time you are not receiving errors and your UI isn’t getting updated how you would expect — particularly if you code communicates with the network, a serial device, or other device which communicates asynchronously.

Thread-Safe Generic Dictionary

The following question was posted on MSDN forums last night and I thought I’d take a little time to answer this considering my apparent threading affinity (*cough*). Here was the question:

“Could someone give me a pointer as to how I might implement a thread safe wrapper around a genric dictionary? I’ve written thread-safe dictionaries in C# 1.x by inheriting from the DictionaryBase but I’m a bit stumped as to how to acheive this using Generics.”

I can certainly understand the complaint here. It comes from the fact that Microsoft apparently didn’t think anyone would need thread-safe generic collections — or if you did, you should do your own work on this. Think I’m wrong? Consider this link, which states:

A System.Collections.Generic.Dictionary<,> can support multiple readers concurrently, as long as the collection is not modified. Even so, enumerating through a collection is intrinsically not a thread safe procedure. To guarantee thread safety during enumeration, you can lock the collection during the entire enumeration. To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization.

What this means is that you have some limited options. 1) Create a sub-class of System.Collections.Generic.Dictionary, 2) Create a utility class for modifying the collection safely, or 3) Creating your own thread-safe dictionary from scratch.

Lets consider these one by one.

The first option: Sub-Class
This seems a bit rediculous. Your methods might look something like the following:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace ThreadedGenerics {
  class ThreadSafeDictionary : Dictionary {
    public new void Add(T key, U value) {
      // Add your preferred thread locking mechanism here
       base.Add(key, value);
      // unlocking here
    }
    // TODO : Remaining Method Implementations
  }
}

or in VB.NET :

Imports System.Threading
Imports System.Collections.Generic
Public Class ThreadSafeDictionary(Of T, U)
    Inherits Dictionary(Of T, U)
    Public Shadows Sub Add(ByVal key As T, ByVal value As U)
        ' Add your preferred thread locking mechanism here
        MyBase.Add(key, value)
        ' unlocking here
    End Sub
    ' TODO : Remaining Method Implementations
End Class

This is obviously silly because we have to override all of our functionality anyway only to wrap the call in a critical section. You should lock the underlying collection as well, but that’s up to you to decide which method you prefer.

Additionally you have to qualify the method ‘overrides’ with “New” (Shadows in VB.NET) instead of override because Dictionary<,> didn’t mark the functions as virtual. Lets go ahead and scratch this option off the list. It just doesn’t make a lot of sense and violates OO.

The second option: Create a Utility Class

This method seems to make a bit more sense. You simply create a utility class to do all the work for you and do the wrapping. Its cleaner than the “inheritance” method. (I hesitate to call anything inheritance when you can’t override the functionality but rather follow a hide-recall pattern.) This would look something like this:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace NewWinFormsFeatures
{
    public class ThreadSafeDictionaryUtility
    {
       Dictionary dict;
       public ThreadSafeDictionaryUtility() {
            dict = new Dictionary();
        }
        public void SafeAdd(T key, U value) {
            // Add your preferred thread locking mechanism here
            dict.Add(key, value);
            // unlocking here
        }
        // TODO : Remaining Method Implementations
    }
}

or in VB.NET

Imports System.Threading
Imports System.Collections.Generic
Public Class ThreadSafeDictionaryUtility(Of T, U)
    Private dict As Dictionary(Of T, U)
    Public Sub New()
        Me.dict = New Dictionary(Of T, U)
    End Sub
    Public Sub SafeAdd(ByVal key As T, ByVal value As U)
        ' Add your preferred thread locking mechanism here
        Me.dict.Add(key, value)
        ' unlocking here
    End Sub
End Class

This should work pretty well but it isn’t the most efficient way to get what you want. It does, however, prevent you from performing much implementation. You basically only provide the implementation methods you want and you simply wrap them into a critical section or object lock.

The third option: Rolling your own

This last option requires you to create your own implementation from scratch. This would require you to create a class that implemented the IDictionary<,> interface (and any others that you want to implement such as ISerializable). I wont get into details here because to do this right, you really need to do a lot of work and its already 3am here 🙂 What I will say is that Microsoft does state that DictionaryBase is not thread safe. What it does use is the BeginCriticalRegion and EndCriticalRegion methods to let the host know that exceptions in portions of the “add” code may be damaging to other code in the AppDomain. After waking up this morning and reviewing this code (per a very kind individual who bluntly pointed out my error) I feel its neccessary to write an explaination of what those methods do and when its not appropriate. BeginCriticalSection and EndCriticalSection around the ENTIRE Dictionary.Add method would be inappropriate. Where it would be appropriate to use these functions is in this third option — rolling your own. You want it around the very small portion of the code that does the array shifting and modifying of the underlying value. Otherwise, in the case of wrapping it around the Dictionary.Add method, something as simple as an invalid argument passed into your thread-safe class may cause the entire appdomain to shut down.

HTH.

Thread Switching Overhead

I was reading a post by Sue Loh today. It gives a very cool insight into some threading problems with an expedited thread quantum on CE. Essentially, since threads have half the time to do their actual work, the thread context switching overhead percentage provides a bigger hit on performance. Putting this in a real-world situation , I state it like this. I am currently driving 1.5 hours to work and back (each way) so I spend a tremendous amount of time on the road. Of course, I put in 9 hour days or so. Most people feel this is a lot of distance to drive, and I agree (hense why I’m moving to Greenville, SC this weekend). However, imagine if I had to drive to work in the morning, put in 4 or 5 hours of work, then drive home and back and put in another 4 or 5 hours of work. I’d be spending just about as much time going back and forth to work as I did actually working. This is the same problem with the expedited thread quantum. Sue sites the difference of 100 milliseconds that is set by default in CE to 50 miliseconds that an OEM might change this value to. Keep in mind that if you change the amount of work that can be done in a single pass, there is some overhead in the context switching that will be much more evident with the actual work cycles being truncated.

Pro .NET 1.1 Remoting, Reflection and Threading

I received 10 shiny copies of my new book that is now available at BarnesAndNoble.com (or amazon.com if you really must buy through them). Its a pretty interesting mix of technologies from .NET that helps bring a novice programmer up to date. While I’m much more of a C# programmer these days, based on my VB background this book was necessary. My reasoning can be found on the back cover of the book:

“Dear Reader,

Rapid Application Development has long been the purpose and strong point of a Visual Basic Developer. In the past VB versions, we had to solve more complex problems than the language designers ever intended. Of course, this fed the flames of those language elitists that said VB was an inferior language. With the introduction of .NET, many VB developers were overwhelmed with the task of learning programming in the object-oriented paradigm that was, perhaps, completely new to them; couple that with learning the .NET libraries, the CLR, and changes in the language we had been using for years, and many developers initially found it hard to shoulder the burden.

Coming from a VB background, I see firsthand how many developers barely have the time to grasp these concepts, let alone the additional intricacies of some of the more powerful features newly available to VB developers in the .NET world. Those powerful topics, as the book title suggests, are Remoting, Reflection and Threading. This book is compiled to help VB developers reinvigorate their learning by adding these powerful new skills to their tool belts. The topics in this book can help you take a standard application from satisfactory to out-standing. By adding background processing through threading, scalability with remoting, and extensibility with reflection, you can give your applications a uniquely professional touch. The details in this book will show you how to add these powerful features to your applications and will prepare you to compete head to head with other language developers.”

Anyway, I’m excited because this is my first hard cover book. Bill has already had his say on that topic. Donbt worry Bill, Ibm writing another book now in my spare time that will probably be written on tissue paper and covered with newspaper and finger-paint.

Updating Controls From Worker Threads

I thought this was an issue that has been hashed over enough times, but the other day I was asked this question and I’m still amazed that many folks are unfamiliar with this concept.

In WinForms applications, sometimes its desirable to execute a long running method in a worker thread. For instance, you may be retreiving data over a web service that has a heavy load and usually takes several seconds to execute.. When the work has completed, it’s typical that you would want to update the user interface: be that a grid, a tree view control, or some other container that displays the results of your call to the long running process.  Sounds simple enough right?

Before you get in a hurry, consider one thing.  Data created on one thread is owned by that thread as long as it is local data.  This can be overcome though by marshaling the data across threads.  This is a function of Thread Local Storage implemented through managed code. Virtual address space of a process is shared across all threads.  While the data of a thread is unique, it can be “shared” or copied but you need to tell the application to copy the data to a the UI thread before updating the UI with the data.  This can be done using Control.Invoke().

Take a look at what happens when you don’t use this method.  Createa  new Windows Forms project, add a TreeView control (tvResults) and two buttons.( btnNormalExe and btnThreadExe ).  Add the following methods on the form:

public void WorkerThread() {
    Cursor.Current = Cursors.WaitCursor;
    // Simulate Long Process (5 seconds)
    Thread.Sleep( new TimeSpan( 0,0,0,5,0 ) );

    UpdateResults();
    Cursor.Current = Cursors.Arrow;
}

public void UpdateResults() {
  // Update UI
  tvResults.Nodes.Add(
    String.Format( "UI Updated on Thread ID {0} at {1}", 
       AppDomain.GetCurrentThreadId().ToString(),
       DateTime.Now.ToString() ) );
}

For btnNormalExe add the following code:

 

private void btnNormalExe_Click(object sender, System.EventArgs e) {
  WorkerThread();
}

For btnThreadExe add the following code:

private void btnThreadExe_Click(object sender, System.EventArgs e) {
  Thread t = new Thread( new ThreadStart( WorkerThread) );
  t.Start();
}

Now run the form and click on the normal execution button first. Once the method completes, click on the thread execution button.  You’ll receive an exception when the threaded execution completes:

An unhandled exception of type 'System.InvalidOperationException' 
occurred in system.windows.forms.dll
Additional information: The action being performed on this control 
is being called from the wrong thread. You must marshal to the 
correct thread using Control.Invoke or Control.BeginInvoke to 
perform this action.

Just as the exception says, we are going to modify our call to make sure we get back on the UI’s thread before updating it.  In this way, the form’s thread owns the data, not the worker thread. Modify the UpdateResults() method as follows:

public void WorkerThread() {
  Cursor.Current = Cursors.WaitCursor;
  // Simulate Long Process (5 seconds)
  Thread.Sleep( new TimeSpan( 0,0,0,5,0 ) ); 

  //UpdateResults(); 
  this.Invoke( new TreeViewUpdater( UpdateResults ) ); 
  Cursor.Current = Cursors.Arrow;
}

Notice that when you execute both the normal execution button and the threaded execution button the tree view control updates with the same thread ID. This is because the call to control.Invoke puts the call back on the form’s thread.

I will cover this in more depth in the weeks to come, to shed more light on what’s happening in the background.