Maybe this is more of a "how do you report progress" topic.

I have a progress bar on a form. The same form launches 2 separate threads. I would like each thread to report to the same progress bar.

Instead of cluttering my code up with a bunch of stuff like progressBarOverall.value += 10; .

I've used progress bars before for tasks with loops, and they work extremely well, but what about tasks with no loop? or tasks with multiple loops? Or even better...tasks with multiple loops but determining the number of times a loop must occur is a long process itself?

I know how to actually update the values of the progressbar from the threads, I'm just wondering if I have to keep calling stuff like progressBarOverall.value += 10; over and over again to update it?

Oh yeah...forgot to say I'm not threading with background workers...I'm using thread.start() and the like.

Recommended Answers

All 6 Replies

hey there,

well you should use a lock, and don't forget to use invoke to update the progressbar. You can call this function when there is an actual progress:

private void reportprogress()
        {
            if (InvokeRequired)
            {
                Invoke(new Action(reportprogress));
            }
            else
            {
                lock (this)
                {
                    if(progressBar1.Value+10<=100) progressBar1.Value += 10;
                }
            }
        }

I hope this helps!

Its not a great idea to just spinning off threads like that, if you have some lengthy processes that needs to be done on a separate thread it might be best to do them in the same worker thread one after another, especially if the main program isn't going to be continuing on till both are done. Unless the user has a quad core processor, there will be no speed benefit from using 2 worker threads.

A background worker control is a good way to do simple synchronous operations like this. Reporting progress is simple, and you can pass to, and back from the worker thread an object very easily. that object could be an object array that has an infinite amount of information. Plus there is a lot of examples out there to work from.

Thanks for the replies!

I do use locks, and invoke...that was a quick lesson that i learned when i first started threads.

I do understand that performance may not increase with using the threads unless someone has a CPU that is capable of processing them in a quicker fashion. I decided to use separate threads for these two functions because the two functions are completely unrelated and could be called later on in different code one at a time. If I combine the methods and use one thread, I lose the ability to run one and not the other without adding an if or switch to the code, which is unnecessary.

The threads are used because without it, the UI was hanging and wasn't processing any UX updates. Even with passing Application.DoEvents(), it did nothing. After starting the threads, they complete flawlessly now, and the UI never hangs. I'm extremely happy.

The methods themselves are rather uncomplicated, but they query the network for SQL servers and check system services for running servers to help configure the application. When the methods to query the network and the services are called the thread it is called on stops until the other method completes, which involves waiting for responses from network devices and services.

I agree that creating threads just for the fun of it is kind of useless and, if they are anything like the problems I had learning where the thread was dieing and which one it was, it would be stupid to want to debug something like that...my head hurts again just thinking about it.

You can easily use separate methods and call them from the one thread and retain that reusability. But that's up to you friend. As long as it works.

Hmmm....good point. I might look into that.

you might want to do something like this.
separate the methods into two separate classes. In each class have a delegate and event to notifyofprogress. Then when you create the class, tie the event to a local method that reports progress. Here is some pseudo-code

public class DoMethod1
{
  public delegate void delNotifyOfProgress(int cnt);
  public event delNotifyOfProgress NotifyOfProgress;

// other private fiels and accessors you might need

public void DoThreadedMethod()
{
  int cnt = 0;  //integer to track progress
  // do the work
  if (NotifyOfProgress.GetInvocationList().Length > 0)
    NotifyOfProgress(cnt);
}
}

your main thread would implement it like this

private void someMethod()
{
  DoMethod1 dm1 = new DoMethod1();
  dm1.NotifyOfProgress += new DoMethod1.delNotifyOfProgress(progressReport);
  Thread thrd  = new Thread(dm1.DoThreadedMethod);
  thread.Start();
}

private void progressReport(int cnt)
{
  lock(object)  // create object to lock, don't do this: lock(this)
  {
  //implement progress bar here
  }
}

This will get you going in the right direction. Disclaimer...wrote from memory so there might be some syntactical errors. Also, there are ways you can optimize.
Couple of points, don't forget the lock statement where you run the progress update. Also recommend creating an object just for the purpose of controlling thread.

Also in the class, don't forget the GetInvocationList on the event. That way, if you ever want to use the thread without tieing the event back to a method, you can do so.
Good luck

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.