您好 我正在尝试将后台工作程序与进度条集成,但无法使其正确。
我正在处理一些文件,所有处理都在外部类中完成。
我的困难在于循环是在这个课程中,通常我会和背景工作者交谈。
好处是,在处理文件时,只要每个文件都已完成处理,就会触发事件。
这是我的代码,任何建议如何实现
BackgroundWorker _bw = new BackgroundWorker
private void RunLongProcess()
{
_bw.WorkerReportsProgress = true;
_bw.WorkerSupportsCancellation = true;
_bw.DoWork += DoWork;
_bw.ProgressChanged += ProgressChanged;
_bw.RunWorkerCompleted += RunWorkerCompleted;
_bw.RunWorkerAsync();//start the process
if (_bw.IsBusy)
_bw.CancelAsync();
}
static void DoWork (object sender, DoWorkEventArgs e)
{
var files=GetFiles();
int fileCount=files.Count;
//usually I do a loop here but all the processing is done inside this class so
var fileProcessor=new FileProcesser();
fileProcessor.ProcessFiles(files);
}
private void OnFileProcessCompleted(object sender, FileEventArgs e)
{
//Event Fired when a file has been processed
//How do I update progressBar.Problem cross threading here.
//What do I do here?????
_bw.ReportProgress(e.FileProcessedCount, e);
}
ProgressChanged (object sender, ProgressChangedEventArgs e)
{
// Update the UI
labelProgress.Text = e.UserState;
progressBar.Value = e.ProgressPercentage;
}
private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
// Console.WriteLine("You canceled!");
else if (e.Error != null)
//Console.WriteLine("Worker exception: " + e.Error.ToString());
else
// Console.WriteLine("Complete: " + e.Result);
}
答案 0 :(得分:2)
_bw.ReportProgress(e.FileProcessedCount, e);
不应该进入OnFileProcessCompleted
。 DoWork
完成时会触发此事件。您应该将其放在DoWork
中以更新进度条。所以它看起来像这样:
private void DoWork (object sender, DoWorkEventArgs e)
{
BackgroundWorker bg = sender as BackgroundWorker;
var files = GetFiles();
int fileCount = files.Count;
var fileProcessor = new FileProcesser();
for(int i = 0; i < fileCount; i++)
{
fileProcessor.ProcessFile(files[i]);
bg.ReportProgress( (uint)((i / (double)fileCount) * 100));
}
}
我会将BackgroundWorker传递给FileProcessor,如下所示:
private void DoWork (object sender, DoWorkEventArgs e)
{
BackgroundWorker bg = sender as BackgroundWorker;
var files = GetFiles();
int fileCount = files.Count;
var fileProcessor=new FileProcesser(bg);
fileProcessor.ProcessFiles(files);
}
在FileProcesser中,它看起来像这样:
private BackgroundWorker _bg;
public FileProcessor(BackgroundWorker bg)
{
_bg = bg;
}
public void ProcessFiles(Files files)
{
// Process files
// ...
// Report Progress
_bg.ReportProgress(e.FileProcessedCount, e);
}
答案 1 :(得分:0)
在这种情况下,一种解决方案是从BackgroundWorker
创建派生类,使其订阅事件,并将progress事件发送到事件处理程序中的UI线程。