我有一个C#(WPF)程序搜索目录中的文件,我想要一个进度条来显示我在目录中搜索文件的进度(因为目录中可能有数千个文件)。
我决定使用后台工作人员,以便正确更新进度条(这不会发生,但这不是我最大的问题)。
目前发生的事情是SOMETIMES的工作非常奇怪,但大多数时候我都会遇到这个错误。我唯一没有收到此错误的方法是,如果我在MessageBox.Show();
循环中添加foreach(document in myDirectory)
来减慢速度并查看其中的数字文件。然后它只会经常出错。
任何人都可以向我解释为什么我会收到此错误,以及如何解决此问题?此外,如果您认为有更好的方法来显示进度条,请不要犹豫,纠正我正在做的事情。
我的错误
类型' System.InvalidOperationException'的例外情况发生在System.dll中但未在用户代码中处理
附加信息:此操作已经调用了OperationCompleted,并且进一步调用是非法的。
myApp.xaml.cs
BackgroundWorker backgroundWorker1;
public void searchFiles()
{
//50 files in the directory
int fileCount = 50;
int documentCounter = 0;
//For every file in the directory
foreach(document in myDirectory)
{
//increment the file count
documentCounter++;
FileSearchProgressBar(documentCounter, fileCount);
}
}
private void FileSearchProgressBar(int currentDocNumber, int count)
{
backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.DoWork += (obj, ea) => CalculateProgress(currentDocNumber, count);
backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(progressReport);
backgroundWorker1.RunWorkerAsync();
}
void progressReport(object sender, ProgressChangedEventArgs e)
{
progBar.Value = e.ProgressPercentage;
}
private void CalculateProgress(int currentDocNumber, int count)
{
//This is where the error is reporting
backgroundWorker1.ReportProgress(currentDocNumber * (100 / count));
}
EDIT1
堆栈跟踪
System.InvalidOperationException: This operation has already had OperationCompleted called on it and further calls are illegal.
at System.ComponentModel.AsyncOperation.VerifyNotCompleted()
at System.ComponentModel.AsyncOperation.Post(SendOrPostCallback d, Object arg)
at System.ComponentModel.BackgroundWorker.ReportProgress(Int32 percentProgress, Object userState)
at System.ComponentModel.BackgroundWorker.ReportProgress(Int32 percentProgress)
at HR_Search_Program.MainWindow.CalculateProgress(Int32 currentDocNumber, Int32 count) in c:\Users\myname\Documents\Visual Studio 2013\Projects\myproject\myproject\MainWindow.xaml.cs:line 589
答案 0 :(得分:1)
您发布的代码甚至无法编译。这在语法上是不正确的。如果没有可靠地再现问题的a good, minimal, complete code example,就不可能确切地知道问题是什么,更不用说最好的解决方案是什么。但是你的帖子中有一些线索:
ReportProgress()
对象上调用BackgroundWorker
方法。BackgroundWorker
的代码会为myDirectory
集合中的每个文档创建一个新实例,并将此新实例的引用分配给单个变量backgroundWorker1
。由于您有多个BackgroundWorker
并发运行的实例,但一次只能跟踪一个实例,因此很可能以后启动的实例首先完成,而之前启动的实例正在尝试报告进度,但只能使用稍后启动的实例的引用。由于后来启动的实例已经完成,因此抛出了异常。
一种解决方法是简单地将CalculateProgress()
方法作为参数发送到BackgroundWorker
事件处理程序的DoWork
引用。这样,BackgroundWorker
的每个实例都会使用本身来报告进度,而不是尝试使用最近启动的进度。
但似乎不太可能在一开始就使用多个BackgroundWorker
实例。更好的实现是BackgroundWorker
的单个实例,其中枚举文档的循环位于该worker的DoWork
事件处理程序中。
我希望以上内容足以让您识别代码中的错误并进行修复。如果没有,请提供一个很好的代码示例,以便对其进行修改,以便说明我的意思。