我有Add button click event
如何添加文件:
private void btnAddfiles_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
foreach (String file in openFileDialog1.FileNames)
{
System.IO.Stream stream;
try
{
if ((stream = openFileDialog1.OpenFile()) != null)
{
using (stream)
{
StartBackgroundFileChecker(file);
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
}
}
}
}
我传递给StartBackgroundFileChecker(string file)
的每个文件都需要打开进程并在添加到ListBox
之前检查此文件,所以我通过BackgroundWorker
执行此操作以防止我的GUi冻结并完成所有工作:
private void StartBackgroundFileChecker(string file)
{
ListboxFile listboxFile = new ListboxFile();
listboxFile.OnFileAddEvent += listboxFile_OnFileAddEvent;
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.DoWork +=
(s3, e3) =>
{
//check my file via another class
};
backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
(s3, e3) =>
{
///
});
backgroundWorker.RunWorkerAsync();
}
当我完成阅读我想要更新我的UI的所有文件时,如果我将此Ui更新放在backgroundWorker.RunWorkerCompleted...
内,它会在每次调用此函数后更新我的UI,并且我正在寻找方法来执行此操作在所有电话结束时
答案 0 :(得分:3)
最简单的方法是保持柜台。
private int numWorkers = 0;
然后在启动每个后台工作程序时递增它。
using (stream)
{
Interlocked.Increment(ref numWorkers);
StartBackgroundFileChecker(file);
}
将相同的方法分配给每个后台工作者完成的事件。
backgroundWorker.RunWorkerCompleted += myCommonCompletedHandler;
在已完成的活动中减少计数器。
public void myCommonCompletedHandler(object sender, RunWorkerCompletedEventArgs e)
{
if(Interlocked.Decrement(ref numWorkers) == 0)
{
// all complete
}
}
答案 1 :(得分:1)
您只能使用此方法BackgroundWorker
。
BackgroundWorker backgroundWorker;
private void btnAddfiles_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
backgroundWorker = new BackgroundWorker();
backgroundWorker.WorkerReportsProgress = true;
backgroundWorker.DoWork +=
(s3, e3) =>
{
StartBackgroundFileChecker(openFileDialog1.FileNames);
};
backgroundWorker.ProgressChanged +=
(s3, e3) =>
{
//example:
this.progressBar1.Value = e.ProgressPercentage;
};
backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
(s3, e3) =>
{
///End Here!!
});
backgroundWorker.RunWorkerAsync();
}
}
private void StartBackgroundFileChecker(string[] files)
{
for (int i = 0; i < files.Length; i++)
{
string file = files[i];
System.IO.Stream stream;
try
{
if ((stream = openFileDialog1.OpenFile()) != null)
{
using (stream)
{
ListboxFile listboxFile = new ListboxFile();
listboxFile.OnFileAddEvent += listboxFile_OnFileAddEvent;
//Other things...
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message);
}
backgroundWorker.ReportProgress((i+1) * 100.0/files.Length, file);
}
}
答案 2 :(得分:-1)
我只是遇到了同样的问题,这对我有用。
private void Worker_DoWork(object sender, EventArgs e)
{
if (Worker.IsBusy == false) { //...Finished execution }
}
答案 3 :(得分:-3)
为防止用户界面冻结,您可以执行以下操作:
while (BackgroundWorker.IsBusy()) {
Application.DoEvents();
}
我从msdn docs here
开始