我为BackgroundWorker和进度条实现了'CheckFileSize()'功能,因为搜索任务可能需要很长时间。自添加BackgroundWorker线程以来,应用程序时间似乎要慢得多......如何优化,或者我做错了什么?
private void UploadApp()
{
label4.Visible = true;
label4.Text = ("Please wait...");
// Assign BackgroundWorker1 to start check file size.
backgroundWorker1.RunWorkerAsync();
}
// Check for invalid file size in 'AppID' folder.
private void CheckFileSize()
{
// Set application directory.
string AppDirectory = ("Z:/Projects/" + AppID);
// Set maximum file size in byte size (2GB).
long fileSizeLimit = 2000000000;
// Get IEnumerable (as in a list) on all files by recursively scanning directory.
var fileList = Directory.EnumerateFiles(AppDirectory, "*", SearchOption.AllDirectories);
// Retrieve the size of files.
long fileSize = (from file in fileList let fileInfo = new FileInfo(file) select fileInfo.Length).Sum();
// Exit application utility if maximum file size found.
if (fileSize >= fileSizeLimit)
{
//MessageBox.Show("Project folder '" + AppID + "' contain file size greater than or equal 2GB. Manual SCM upload required.");
DialogResult MsgResult;
MsgResult = MessageBox.Show("Project folder '" + AppID + "' contain file size greater than or equal 2GB. Manual SCM upload required.",
"Invalid File Size",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
Environment.Exit(0);
}
}
// BackgroundWorker1 runs 'DoWork' in the background to check invalid file size.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Set for loop to increment progress bar.
for (int i = 0; i <= 100; i++)
{
CheckFileSize();
// Method to report the percentage complete.
backgroundWorker1.ReportProgress(i);
// Cancel BackgroundWorker1.
if (backgroundWorker1.CancellationPending)
{
break;
}
}
}
// Update the progress bar control when the worker thread reports progress.
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
// Enable START and EXIT button when work is done or thread is cancelled.
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
button1.Enabled = true;
button2.Enabled = false;
button3.Enabled = true;
}
}
答案 0 :(得分:0)
你在一个循环中调用CheckFileSize,这是非常昂贵的。您最好使用FileSystemWatcher来通知您对文件的任何更改。然后,您可以跟踪每个文件大小更改并相应地更新总计。
答案 1 :(得分:0)
我认为这不是BackgroundWorker
报告进展的方式。你在做什么:
CheckFileSize
方法100次据我所知,CheckFileSize
的所有100次运行都做同样的事情。结果可以改变的唯一方法是在运行之间目录的内容是否发生变化。所以,问题是 - 您希望在代码运行时更改文件吗?
如果没有,那么您应该只运行CheckFileSize
一次。如果需要报告进度百分比,则必须在方法中执行此操作:
var fileList = Directory.GetFiles(AppDirectory, "*", SearchOption.AllDirectories);
int fileCounter = 0;
long fileSize = 0;
foreach (string file in fileList)
{
fileSize += new FileInfo(file).Length;
if (fileSize >= fileSizeLimit)
{
//display message box etc.
break;
}
fileCounter++;
backgroundWorker1.ReportProgress(((double)fileCounter/fileList.Count)*100);
}
这还有另一个优化 - 当达到限制时循环结束,所以我们不必查看其余文件的大小(您的代码总是遍历所有文件)。
如果目录内容可以更改,那么我真的不知道如何显示进度条,我可能会像Tarik建议的那样使用FileSystemWatcher
。
除此之外,我真的不喜欢Environment.Exit
的用法。我相信最好停止BackgroundWorker
,设置结果并在RunWorkerCompleted
处理程序中处理它。