在C#中从线程更新进度条

public class Consumer { Queue queue; Object lockObject; public Consumer(Queue 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 queue; Object lockObject; public int ProgressPercent = 0; int TotalProducedElements = 0; public bool check1 = false; public Producer(Queue 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 queue = new Queue(); 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; } } } 

我有两个类在同一个队列上工作。 一个产生一组整数,第二个是从队列中消耗整数。

在这一切中,我希望按该百分比更新我的进度条。 那么如何在不阻止我的GUI的情况下更新消费者的进度条?

注意我使用了progressbar.Invokedelegate但是没有用。

你需要两件事。 首先显然是一个线程,另一个是调用者。

Invokers将允许您从线程内部更改窗口的控件。 这是一个例子:

 Invoke((MethodInvoker)delegate { Label1.text = "asd"; } 

线程像这样运行:

 some_thread = new Thread (delegate() { { //some_thread code } }); some_thread.Start(); 

您还需要using System.Threading;添加using System.Threading; 在文件的开头。

所以,最终的代码应如下所示:

 some_thread = new Thread (delegate() { { for(;;) { Invoke((MethodInvoker)delegate { //update the progress bar here } } } }); some_thread.Start(); 

您可以使用BackgroundWorker(System.ComponentModel)轻松完成此任务。 看看: http : //www.codeproject.com/Tips/83317/BackgroundWorker-and-ProgressBar-demo

明确:

 while(true) { if(p.ProgressPercent==0) { Thread.sleep(1000); } else { progressBar1.Value=p.ProgressPercent; } } 

更换:

 ProgressPercent = seq; 

 UpdateProgres(seq); 

加:

 public void UpdateProgres(int _value) { if (InvokeRequired) { Invoke(new Action(UpdateProgres), _value); return; } progressBar1.Value = _value; } 

总结您需要的function;

 public void UpdateProgres(int _value) { if (InvokeRequired) { Invoke(new Action(UpdateProgres), _value); return; } progressBar1.Value = _value; } 

或者需要锁定值。 例如;

 while(true) { lock (p.ProgressPercent) { int _p = p.ProgressPercent; } if(_p==0) { Thread.sleep(1000); } else { progressBar1.Value=_p; } }