Updating Progress Bar from Thread in C#
c#
Solution
You need two things. First is obviously a thread, the other is invoker.
Invokers will let you change window's controls from inside of a thread. Here's the example:
Invoke((MethodInvoker)delegate
{
Label1.text = "asd";
}
Threads are ran like this:
some_thread = new Thread
(delegate()
{
{
//some_thread code
}
});
some_thread.Start();
You also need to add `using System.Threading;` at the beginning of the file.
So, the final code should look like this:
some_thread = new Thread
(delegate()
{
{
for(;;)
{
Invoke((MethodInvoker)delegate
{
//update the progress bar here
}
}
}
});
some_thread.Start();
Problem
``` public class Consumer { Queue<int> queue; Object lockObject; public Consumer(Queue<int> queue, Object lockObject) { this.queue = queue; this.lockObject = lockObject; } public void consume(string filepath) { int item = 0; while (true) { lock (lockObject) { if (queue.Count == 0) { Monitor.PulseAll(lockObject); continue; } item = queue.Dequeue(); if (item == 0) { break; } //do some staff } } } } public class Producer { Queue<int> queue; Object lockObject; public int ProgressPercent = 0; int TotalProducedElements = 0; public bool check1 = false; public Producer(Queue<int> queue, Object lockObject) { this.queue = queue; this.lockObject = lockObject; } private bool IsPrime(int num) { if (num == 0) return true; num = Math.Abs(num); for (int i = 2; i <= Math.Sqrt(num); i++) if (num % i == 0) return false; return true; } public void produce(int target) { try { int seq = 0; while (seq++ < target) { lock (lockObject) { int item = seq; if (IsPrime(item)) { queue.Enqueue(item); } TotalProducedElements++; ProgressPercent = seq; if (queue.Count == 0) { Monitor.PulseAll(lockObject); } } } queue.Enqueue(0); } catch (Exception e) { } } } } private void Start_Click(object sender, EventArgs e) { Object lockObj = new object(); Queue<int> queue = new Queue<int>(); Producer p = new Producer(queue, lockObj); Consumer c = new Consumer(queue, lockObj); int target = int.Parse(TargetText.Text); string path = Path.Text; Thread Thread1 = new Thread(() => p.produce(target)); Thread Thread2 = new Thread(()=>c.consume(path)); Thread1.Start(); Thread2.Start(); progressBar1.Maximum = target; while(true) { if(p.ProgressPercent==0) { Thread.sleep(1000); } else { progressBar1.Value=p.ProgressPercent; } } } ``` I have two classes working on same queue. one to produce a set of integers and the second is to consume that integers from queue. And during all this I want to update my progress bar by that percentage. So how to update progress bar from consumer without blocking for my GUI? Note I have used `progressbar.Invoke` and `delegate` but didn't work.