Take the 2-minute tour ×

I am writing a GUI app for monitoring and I'd like to get some advice on it's logic. Basically all the app needs to do is connect to a distant server every x minutes, check if something was changed, get changes if any, act upon them (update local db and so on, depending on changes).

My first idea was:

  1. Have a checkbox (monitoring on/off). On click (if checked) starts a Timer.
  2. Timer launches a BackgroundWorker in it's Tick method.
  3. DoWork method does the connecting / retrieving info stuff
  4. a) on WorkDone handler method gets the info from background worker and does local updates with it b) on WorkDone handler method triggers one or more of custom events "SomethingChanged" depending on changes it got; EventListeners handle local updates from there.

My main problem is calling Worker from Timer since I added Worker to the Form and now they are on different threads (is that correct description?) and then passing results around is a similar problem. I was reading about delegates but still not sure what to use when and how, and if it's really necessary in the first place. Do I need both bgWorker and Timer? Do I need custom events or can I just do all work inside workDone with Switch(result)? Is this general principle good in the first place, maybe there's something better and I am reinventing the wheel? Thank you in advance!

share|improve this question

3 Answers 3

up vote 2 down vote accepted

From an architecture point of view:

Message Queues decouple bits of your application. You can in Windows Forms applications rely on the Message Queue that Windows creates and manages for you. Google for PostMessage/GetMessage etc. This is generally called "message passing".

Typical Arcitecture

  • One part of your app "pushes" a request into a queue
  • Some other part of your app "pulls" a request from a queue and writes a result to a second queue.
  • The first part can then "pull" requests from the second "results" queue and display to a user.

So it looks like this:

App --> REQUESTS QUEUE --> processing engine --> RESULTS QUEUE --> App

The processing engine could be in the same app, on the same thread or in a different thread/process (or even different machine).

You can use simple queues : say a Queue<string>() (as long as you use locks to access it) or increase complexity or more and more complex/functional queues.

Issues with the naive strategy and other solutions ... things to think about:

  1. What happens if you make a new request while the old one has not yet completed?
  2. What happens if an error occurs? Do you want errors inline? You can use another queue for errors?
  3. Do you want retries?
  4. What happens if a message is lost? (i.e. a request was pushed, but no response comes in...)? There are transactional queues etc.

Sample Code

    object oLock = new object();
    Queue<string> requests = new Queue<string>();
    Queue<string> responses = new Queue<string>();
    Thread mThread;
    AutoResetEvent mEvent = new AutoResetEvent(false);

    public Form1()
        mThread = new Thread(ProcessingEngine);
        mThread.IsBackground = true;

    private void ProcessingEngine()
        string result;
        string request = null;

        while (true)

                lock (oLock)
                    request = requests.Dequeue();

                var wc = new WebClient();
                result = wc.DownloadString(request);

                lock (oLock)
            catch (Exception ex)
                lock (oLock)

    private void timer1_Tick(object sender, EventArgs e)
        lock (oLock)
            //Stick in a new request

            //Allow thread to start work

            //Check if a response has arrived
            if (responses.Any())
                var result = responses.Dequeue();
share|improve this answer

If you use System.Windows.Forms.Timer instead of System.Threading.Timer, your Tick handler will be called from Form's message loop and you'll have full access to all controls - it will be safe to call bgWorker.RunWorkerAsync(). As for retrieving results - RunWorkerCompleted is also called from message loop thread and you can safetly update your UI here.

share|improve this answer
-1. This destroys scalability and if the thread forexample times out - the UI will block until the timeout happens, which is bad. Using Threading.Timer allows the execution on a separate thread, then invoking back to the main thread (Invoke method on window) for just the UI updates. –  TomTom Dec 4 '11 at 8:53
How come? I have yet to see case when RunWorkerAsync blocks for any noticable time, you can't update UI from Threading.Timer.Tick directly and using Invoke in Timer gives you exactly same results as updating it from RunWorkerCompleted. DoWork executes in it's own thread so please explain why do you think UI would block. –  MagnatLU Dec 4 '11 at 10:57
Comp vote, there's nothing wrong with doing it this way. No blocking ever occurs, trying to run a busy BGW produces an exception. With either kind of timer. At least it relaxes the OP's concern for having too many threads. –  Hans Passant Dec 4 '11 at 11:06

The solution is simple - INVOKE back into the main thread. THere is an Invoke method on the winform control. This will basically change threads for execution to the UI thread, and allow you to manipulate the UI.

Do that "block" (i.e. not once per control but once when you have news).

share|improve this answer

Your Answer


