Tag: threading

C# Dev Connect 1 – Intro To Threading

C# Dev Connect

C# Dev Connect 1: Intro to Threading

In my last post, I mentioned we’d be hosting a C# Dev Connect meetup at our Magnet Forensics HQ in Waterloo. I figured I’d post to talk about how the event went so that if you couldn’t make it, you’ll have an idea for next time (and if you did make it, maybe you can comment on how you thought the event went). Our first Dev Connect was lead by a colleague of mine, Chris Sippel, who wanted to give a talk on threading basics in C#. Threading can quickly become a really complex topic, so Chris wanted to keep it high level and talk about the different approaches you can use to start threading in your C# applications.

Dev Connect: Before the Talk

Before Chris gave his talk on threading, we had our attendees slowly streaming in. Sure, we had a lot of our Magnet development team show up to offer support for Chris, but I was still pleasantly surprised to see others from the area that I’ve never met before showing an interest in C#. Our colleague Amaris had done an awesome job coordinating the first event for us, and even got us stocked up with pizza and pop. For the first hour or so, we had our guests fed and introduced to each other. A great start to the evening!

Dev Connect: The Talk

After everyone was settled in, we had our attendees pull up some chairs at tables or post up in our comfy soft seating to listen to what Chris had to say. Chris walked us through various slides and coding examples and was able to show us working examples of code to back up what he was saying. I was really proud of Chris for taking the leap to be our first speaker, and I think he did a great job. His slides and sample code are available at the Dev Connect git hub if you’re interested in taking a peek.

Dev Connect: The Aftermath

Once Chris was done talking, we had a few attendees leave to carry on with the rest of their evening, but it was great to see the majority hang back for further discussion. Some people were trying out the threading exercises that Chris had put together, others had tried it beforehand and had questions on it, and a bunch of people were sticking around just to talk .NET. When I envisioned what Dev Connect might have looked like, this was it. It felt great to help facilitate a positive discussion around using the .NET framework and C#, especially because people were clearly benefiting from it.

If you came for our first meetup, then thanks! If you couldn’t make it or you’re interested in the next one, be sure to check out our meetup page. We’ll see you next time!


First C# Dev Connect is Coming Up

C# Dev Connect

 

C# Dev Connect Meetup!

About a year ago I had thrown around the idea of creating a C#-specific group that would meet at a regular interval with some of my colleagues. I saw that there was interest, but between all of the things we had going on in our personal lives and work lives, we just hadn’t been able to co-ordinate something. I’m excited to announce that with some more solid planning over the last couple of months, C# Dev Connect will be able to host their first meetup! The company I work for, Magnet Forensics, has graciously offered our new office to host the event which will help tremendously. We’ll have a group of people from Magnet Forensics their to help out, but the only thing “Magnet” about the event is really just that it’s hosted at the office.

What’s on the Dev Connect Agenda?

This upcoming Tuesday (Tuesday January 20th, 2015) C# Dev Connect will be hosting their first monthly meetup on the topic of Threading in C#. Directly from the event’s Meetup page:

Overview of the the basics of threading in C# language. Threading is a very complex idea with many different ways of handling the same problem, however, you have to learn to crawl before you can walk. We’ll be discussing the basics of threads in .NET 2.0 and .NET 4.0. In .NET 2.0 we’ll be discussing the Thread object, various ways to start/stop threads, and potential stumbling blocks when it comes to threading in C#. In .NET 4.0 we’ll be talking about the async and await operators and how to use them.

A colleague of mine, Chris Sippel, will be giving the talk. People are encouraged to bring their laptops so they can try out some C# exercises related to the discussion. This initial talk may be more geared at an introductory-level, but our goal is to be able to cover topics for all levels of knowledge in C# (From never used it before, to expert level). We’ll even provide some food! All you have to do is show up and be ready to learn some C#, or share your C# knowledge.

If you’re looking for our venue, we had this little map put together:

C# Dev Connect Venue Map

Go into the back of 156 Columbia Street West in Waterloo (at the corner of Phillip and Columbia). If you’re familiar with the area, this used to be called RIM/Blackberry 5.

 

More Dev Connect Info

Here are a few additional links to get you to more C# Dev Connect information online:

We’re excited for you to join us!


Simple Way To Structure Threads For Control

Background

I’ve previously discussed the differences between the BackgroundWorker and Thread classes, but I figured it would be useful to touch on some code. I’d like to share the pattern I commonly use when creating threads in C# and discuss some of the highlights.

The Single Thread

I like to use this design when I have a single thread I need to run and in the context of my object responsible for running the thread, I do mean having a single thread. Of course, you could have your object in control of multiple threads as long as you repeat this design pattern for each of them.

Here’s the interface that I’ll be using for all of the examples:

    internal interface IThreadRunner
    {
        #region Exposed Members

        void Start();

        void Stop();

        #endregion 
    }

Behold!

    internal class SingleThreadRunner : IThreadRunner
    {
        #region Fields

        private readonly object _threadLock;
        private readonly AutoResetEvent _trigger;
        private Thread _theOneThread;

        #endregion

        #region Constructors

        /// 
        /// Prevents a default instance of the class from being created.
        /// 
        private SingleThreadRunner()
        {
            _threadLock = new object();
            _trigger = new AutoResetEvent(false);
        }

        #endregion

        #region Exposed Members

        public static IThreadRunner Create()
        {
            return new SingleThreadRunner();
        }

        public void Start()
        {
            lock (_threadLock)
            {
                // check if already running
                if (_theOneThread != null)
                {
                    return;
                }

                _theOneThread = new Thread(DoWork);
                _theOneThread.Name = "The One Thread";
                _theOneThread.Start(_trigger);
            }
        }

        public void Stop()
        {
            lock (_threadLock)
            {
                // check if not running
                if (_theOneThread == null)
                {
                    return;
                }

                _theOneThread = null;
                _trigger.Set();
            }
        }

        #endregion

        #region Internal Members

        private void DoWork(object parameter)
        {
            var currentThread = Thread.CurrentThread;

            // this was the trigger that we passed in. elesewhere in the 
            // instance, we can use this object to wake up the thread.
            var trigger = (AutoResetEvent)parameter;

            try
            {
                // keep running while we're expected to be running
                while (currentThread == _theOneThread)
                {
                    // DO ALL SORTS OF AWESOME WORK HERE.
                    Console.WriteLine("Awesome work being done.");

                    // put this thread to sleep, but remember it can be woken 
                    // up from other places in this instance.
                    trigger.WaitOne(1000);
                }
            }
            finally
            {
                lock (_threadLock)
                {
                    // if we were still expected to be running, change the 
                    // state to suggest that we're not
                    if (_theOneThread == currentThread)
                    {
                        _theOneThread = null;
                    }
                }
            }
        }

        #endregion
    }

This design was taken from some Java programming I had done in a previous life. Essentially, I have a thread that is responsible for doing some work in a loop. It could be anything… Periodically polling for some data, a work dequeing thread, a random-cursor-moving thread… Anything! The point is, you only want one of these suckers hanging around. How is this accomplished?

Leveraging the instance variable that marks the one expected running thread is key here. Whenever this thread checks if it should still be running, if the current thread doesn’t match what’s assigned to the instance variable then it needs to stop! This means you could potentially spawn off two of these threads, and if you set the instance variable to one of the two, then the other one should kill itself off! Pretty neat.

By using the reset event, we can actually interrupt this thread if it’s sleeping. This is great if we have a thread that periodically wakes up to do some work but we want to stop it and have it stop fast. We simple set our instance variable for the thread to be null and then set this thread’s reset event to ensure it get’s woken up. Presto! It wakes up, checks the condition, and realizes it needs to exit the loop.

Simple.

The Handful of Threads

This design is almost identical to the single thread design above. I use it primarily when I want to have an object responsible for a bunch of threads that are turned on/off under the same conditions. The major difference between the two designs? In the single thread scenario, we check that our current thread is still set to be the one instance. In this design, we need all of our threads to be checking against the same state object which is not going to be a single thread instance.

Let’s have a peek:

    internal class GroupThreadRunner : IThreadRunner
    {
        #region Fields

        private readonly object _threadLock;
        private readonly Dictionary<Thread, AutoResetEvent> _triggers;

        private bool _running;

        #endregion

        #region Constructors

        /// 
        /// Prevents a default instance of the class from being created.
        /// 
        private GroupThreadRunner()
        {
            _threadLock = new object();
            _triggers = new Dictionary<Thread, AutoResetEvent>();
        }

        #endregion

        #region Exposed Members

        public static IThreadRunner Create()
        {
            return new GroupThreadRunner();
        }

        public void Start()
        {
            lock (_threadLock)
            {
                // check if any are already running
                if (_triggers.Count > 0)
                {
                    return;
                }

                _running = true;

                const int NUMBER_OF_THREADS = 4;
                for (int i = 0; i < NUMBER_OF_THREADS; ++i)
                {
                    var thread = new Thread(DoWork);
                    thread.Name = "Thread " + i;

                    var trigger = new AutoResetEvent(false);
                    _triggers[thread] = trigger;

                    thread.Start(trigger);
                }
            }
        }

        public void Stop()
        {
            lock (_threadLock)
            {
                // check if not running
                if (_triggers.Count <= 0)
                {
                    return;
                }

                _running = false;
                foreach (var trigger in _triggers.Values)
                {
                    trigger.Set();
                }
            }
        }

        #endregion

        #region Internal Members

        private void DoWork(object parameter)
        {
            var currentThread = Thread.CurrentThread;

            // this was the trigger that we passed in. elesewhere in the 
            // instance, we can use this object to wake up the thread.
            var trigger = (AutoResetEvent)parameter;

            try
            {
                // keep running while we're expected to be running
                while (_running)
                {
                    // DO ALL SORTS OF AWESOME WORK HERE.
                    Console.WriteLine("Awesome work being done by " + currentThread.Name);

                    // put this thread to sleep, but remember it can be woken 
                    // up from other places in this instance.
                    trigger.WaitOne(1000);
                }
            }
            finally
            {
                lock (_threadLock)
                {
                    _triggers.Remove(currentThread);

                    // if we were still expected to be running, change the 
                    // state to suggest that we're not
                    if (_running && _triggers.Count <= 0)
                    {
                        _running = false;
                    }
                }
            }
        }

        #endregion
    }

Summary

The above patterns I discussed cover my common usage for threads: Instances that have reoccurring work over long periods of time. Both patterns are very similar and only have slight modifications to make them support one instance or many thread instances running. If you have one unique thread or many threads… there’s a pattern for you!

Check out a full working example of this code over here.


Thread vs BackgroundWorker

Background

There are two classes available in the .NET framework that sometimes have some confusion around them: The Thread and the BackgroundWorker. They’re both used to do some heavy lifting for you on a separate thread of execution (so you can keep on keepin’ on), so why do we have two different things to accomplish the same end result

 

Enter The Thread Class

The Thread class is available in the System.Threading namespace. Surprising, right? It’s the basic unit for spawning off work to be done. Threads let you provide them with a name, which could be one advantage to using them. A thread can either operate as “background” which means it will be killed when the application exists, or not as background, which will actually keep the application alive until the thread is killed off.

An instance of the Thread class is relatively lightweight. It’s quick to set up for developers and all you need to do is provide it a method to run. You can put a loop in your thread body to keep it alive and do all sorts of fun stuff. Threads are great for setting up queuing, dequeing, scheduling, monitoring, receiving, and listening logic. Well, there are really countless uses for them, but those are some of the big ones I find I do a lot of.

 

Enter The BackgroundWorker

The BackgroundWorker class is available in the System.ComponentModel namespace. This is slightly different from the Thread class already, and for what it’s worth, I generally only have this namespace around if I’m dealing with a UI. That is, if I’m in the equivalent to a data layer or application layer, I usually don’t have these guys around (usually, but not necessarily always). So is that it then? Just the namespace is different?

The BackgroundWorker class is essentially built on top of the Thread class. The Thread part of the BackgroundWorker is sort of hidden from you. You get to work with two very important parts of the BackgroundWorker though, the DoWork and RunWorkerCompleted events (There’s a progress one too, but because I actually don’t use this much I’ll omit it for you to take on as homework). So… What are these events all about?

The DoWork event is invoked on a separate thread. This is where you want to do your heavy lifting, and you can pass in any object you want when you start up the BackgroundWorker–Simply pull it off of the event args in your DoWork event handler and cast it back to the necessary type. Presto! The RunWorkerCompleted event is what’s triggered when your DoWork event handler finishes up… but the big difference here is that RunWorkerCompleted runs on the thread that started the BackgroundWorker. This is extremely important when you’re working with UIs. Why? Because of cross thread exceptions! UI stuff is generally only run on the UI thread and nothing else. It’s important to note that the DoWork event handler can pass more state to the RunWorkerCompleted event handler by setting a result property on the event args. The RunWorkerCompleted event handler can then take advantage of this data!

My Guidelines

In the end, both of these classes can be used to do work on a different thread than the one you’re currently on. That’s great news. So what are my guidelines for picking one over the other?

  • If you have a long running task that persists, or perhaps something that is running that conceivable have stop/running/paused states (regardless of whether or not you implemented them) you may want a Thread.
  • If you have a task you want to run with the result handled and cleaned up afterward (i.e. a clear distinction between go do this stuff and let me handle the result) then you may want a background worker.
  • If you have a task to be done that you don’t want to block the UI but want to show the result afterward (i.e. loading tons of data to put in a list) then you probably want a background worker.

 

Summary

Threads and background workers can often be used to accomplish the same thing: offloading work to be done on a different thread of execution. I’ve tried to provide my own personal guidelines for when to use either, but there is no law to stop you from doing it as you see fit. As long as you understand what either option provides you, you can make your own decision based on your needs.


  • Nick Cosentino

    Nick Cosentino

    I work as a team lead of software engineering at Magnet Forensics (http://www.magnetforensics.com). I'm into powerlifting, bodybuilding, and blogging about leadership/development topics over at http://www.devleader.ca.

    Verified Services

    View Full Profile →

  • Copyright © 1996-2010 Dev Leader. All rights reserved.
    Jarrah theme by Templates Next | Powered by WordPress