由C#中的多个线程访问的方法使用Progressbar

我有多个线程访问方法。

该方法在线程执行时更新表单上的进度条。

该方法更新我的Windows窗体上的进度条,显示处理文件的进度,因为线程正在完成它们。

您将如何管理该方法以避免死锁。 我无法锁定它,不知道我是做错了,还是我应该在这种情况下锁定它。

public void myWorkerClass() { int amountToScan = 4; lblcount.BeginInvoke( ((Action)(() => lblcount.Text = "Files Checked " + atPDFNumber.ToString() + " of " + amountToScan.ToString()))); decimal percentageComplete = ((decimal)atPDFNumber / (decimal)amountToScan) * 100; backgroundWorker1.ReportProgress((int)percentageComplete); } 

结果是,在最后一行,它告诉我“这个操作已经调用了OperationCompleted,并且进一步的调用是非法的。”

我认为我打开的东西已经被第一个线程或类似的东西处理掉了。

这是一个很好的方法来使用multithreading的进度条(我有正确的想法或原则),或者我的代码中只有一个小错误?

我想如何让这个问题对其他人有价值的是回答这个问题如何在多个线程访问的方法中访问全局变量。 因为我认为这就是这个问题的方向。

看起来你正在使用我不熟悉的BackgroundWorker类。

但是你也要求使用multithreading和ProgressBar的“通用”设计。 这个例子是我从多个线程更新ProgressBar的方法。

首先,你需要一个公共委托(可能在一些帮助类中)

 //is called when the worker-progress is changed public delegate void ProgressChangedHandler(object sender, ProgressEventArgs e); // some own EventArgs public class ProgressEventArgs : EventArgs { public int Percentage { get; private set; } public string Message { get; private set; } public ProgressEventArgs(int percentage, string message) { Percentage = percentage; Message = message; } } 

在每个工人类中,您必须注册该代表

 // event for reporting progress private event ProgressChangedHandler ProgressChanged; // register Eventhandler via dependency injection or own method public void RegisterDelegate(ProgressChangedHandler progressChangedHandler) { ProgressChanged += progressChangedHandler; } 

在包含ProgressBar的UI类中,您需要一种更新进度的方法。 但是对该方法的每次调用都在调用者的线程中执行(使用not-threadsafe UI可能会出现问题)。

为避免这种情况,您可以调用调度程序,以便在UI线程中处理每个引发的事件,而不是工作线程。

 private void StatusUpdate(object sender, ProgressEventArgs args) { if (Dispatcher.Thread.ManagedThreadId != Thread.CurrentThread.ManagedThreadId) { // call from a worker thread var statusUpdateDelegate = new ProgressChangedHandler(this.StatusUpdate); Dispatcher.Invoke(statusUpdateDelegate, DispatcherPriority.Normal, sender, args); } else { // direct call from the UI thread lblProgress.Content = args.Message; pbProgress.Value = args.Percentage; } } 

您可以将此方法作为委托传递给worker

 worker.RegisterEventHandler(StatusUpdate); 

最后,您可以通过每个线程中的事件调用委托

 public void DoVeryHardWork() { // do stuff ProgressChanged(this, new ProgressEventArgs(progress, "some message")); }