Library tutorials & articles

.NET Threading Part I

Race Condition

Let me test your threading prowess. The previous listing contained a race condition. Can you find it? Take a minute or two before continuing. Tic! Tic! Tic!

A race condition is a bug caused by an incorrect assumption as to the timing of two events, that is, that one event would always occur before the other. The race condition occurs when the system shuts down. If the main thread is swapped out in the Wait instance method between testing if the queue length is zero and setting the WaitForComplete flag to true and then the last consuming thread exits the Consume instance method while the main thread is in this state, the event will never be triggered. I ran the code a few hundred times and was never able to trigger the condition. You can't reproduce it because the main thread should be waiting on the event object well before the last consuming-thread exits.

Monitor and Lock

I could have arranged the code otherwise to prevent this race condition, but now I've created another opportunity to introduce you to the System. Threading. Monitor class and the lock C# construct. The monitor design pattern is most familiar to Java developers. In Java, the synchronized keyword allowed the developer to create quick critical sections within their code. The Java construct was often called a monitor.

The .NET framework presents a similar class called the Monitor that implements traditional wait and signal methods called Wait and Pulse. The C# compiler uses this Monitor class to implement a language construct called a lock. The lock is established on an object and while the lock is established, nobody else can acquire the lock and must wait till the lock is freed. I used this lock construct to prevent our previous race condition (see Listing 4).

public void Wait()
{
    lock (this)
    {
        if (QueueLength == 0)
        {
            return;
        }
        Event = new ManualResetEvent(false);
        WaitForComplete = true;
    }
    Event.WaitOne();
}

public void Consume(Object obj)
{
    Console.WriteLine("Thread {0} consumes {1}",
        Thread.CurrentThread.GetHashCode(), //{0}
        ((Ware) obj).id); //{1}
    Thread.Sleep(100);
    lock (this)
    {
        QueueLength--;
        if (! WaitForComplete)
        {
            return;
        }
    }
    if (QueueLength == 0)
    {
        Event.Set();
    };
}

Preventing the concurrent setting and testing of the queue length and WaitForComplete flag by two different threads removes the race condition. The lock ensures that the setting and testing of these two variables is essentially atomic.

Comments

  1. 27 Feb 2004 at 22:06

    I was asked to do the following:
    write the method call to begin running the thread and begin processing
    (a) namespace = testProject
    (b) form to run = frmMain


    All the things that I have read on threading so far say that a thread point to a function of whatever comes after the "addressOf" in the argument.  Therefore, I don't understand what (a) and (b) are trying to refer to or specify.  If you happen to understand what that question is looking for, or know any good literature I can look at for the given topic, please let me know.  Thank you.
    email me

  2. 04 Nov 2003 at 15:04
    Quote:
    [1]Posted by James Crowley on 4 Nov 2003 02:52 PM[/1]
    Are you ensuring that the page doesn't finish loading before both threads have returned a result? Otherwise, you may find that ASP.NET is outputting the page to the client before the thread has actually called the callback!



    Yes...and if I may add, rather hesitantly at this juncture, I did think about that.
    What surprised me however was when I ran this in debugging mode, I as able to trace both callbacks
    and in one case the dataset returned had no data. I wonder if  there are any issues with returning non-simple types
    in the event driven call back. May be, using the delegate mechanism may work. I havn't done
    much callback based threading so far...
  3. 04 Nov 2003 at 14:52
    Are you ensuring that the page doesn't finish loading before both threads have returned a result? Otherwise, you may find that ASP.NET is outputting the page to the client before the thread has actually called the callback!
  4. 04 Nov 2003 at 13:20
    I have tried threading in my web page. I tried to fill two drop-downs by threading two methods in two different business layer objects from my web page. I used the event call back method  to return two datasets (one for each drop down) but got  inconsistent results..drop-downs were populated and sometimes not. Any ideas?
  5. 01 Jan 1999 at 00:00

    This thread is for discussions of .NET Threading Part I.

Leave a comment

Sign in or Join us (it's free).

Randy Charles Morin Randy's article are Copyright 1998-2003 Randy Charles Morin
AddThis

Related podcasts

  • A Practical Look at Silverlight 2 Part 1

    Now that Silverlight 2 is at the Olympics and making a big splash, we wanted to explore this fascinating technology more. Microsoft Silverlight 2 is a cross-browser, cross-platform, and cross-device plug-in for delivering the next generation of .NET based media experiences and rich interactive ap...

Events coming up

  • Nov 18

    15 Minutes of Fame

    Dresher, United States

    This is a yearly tradition. We select 10 of the favorite speakers from monthly meetings, code camps, and hands on labs. Each one does a 15 minute talk on their favorite .NET technology. This is our 10th anniversary so we plan a gala event with special prizes and refreshments.

We'd love to hear what you think! Submit ideas or give us feedback