我不确定invoke是否是正确的使用方式。它运行良好,但我想知道我是否应该使用invoke或其他方式来更新gui控件?如果我想向1个以上的gui控件报告?
现在我正在使用invoke更新label2和listView控件。我应该在什么时候使用invoke,什么时候不使用,然后如何在不调用的情况下更新这个gui控件?
private string pathtosearch;
private int countfiles;
public Form1()
{
InitializeComponent();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
DirSearch(pathtosearch);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
void DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d))
{
Invoke((MethodInvoker)delegate
{
countfiles += 1;
label2.Text = countfiles.ToString();
});
}
DirSearch(d);
}
}
catch (System.Exception excpt)
{
Invoke((MethodInvoker)delegate
{
ListViewCostumControl.lvnf.Items.Add(excpt.Message);
});
}
}
private void button1_Click(object sender, EventArgs e)
{
DialogResult result = folderBrowserDialog1.ShowDialog();
if (result == DialogResult.OK)
{
label1.Text = folderBrowserDialog1.SelectedPath;
pathtosearch = folderBrowserDialog1.SelectedPath;
}
}
private void button2_Click(object sender, EventArgs e)
{
if (textBox1.TextLength > 0)
backgroundWorker1.RunWorkerAsync();
}
使用ReportProgress
方法向UI发送消息,使用ProgressChanged
事件处理消息。
private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
var ex = e.UserState as Exception;
if(ex!= null)
ListViewCostumControl.lvnf.Items.Add(ex.Message);
else
label2.Text = e.ProgressPercentage.ToString();;
}
void DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d))
backgroundWorker1.ReportProgress(countfiles++);
DirSearch(d);
}
}
catch (System.Exception excpt)
{
backgroundWorker1.ReportProgress(countfiles, excpt);
}
}
ReportProgress
可以重载两个参数:一个是用于报告简单"进度"的数字,另一个是对象类型的UserData。如果您想发送丰富的信息,请在此参数中插入您的自定义对象或任何其他具有所需属性的现有对象,另一方面,在ProgressChanged
事件中,将其再次"强制转换"为适当的类型,例如:
ReportProgress
:
backgroundWorker1.ReportProgress(countfiles, Tuple.Create(currFile, "Copying...", timeRem));
ProgressChanged
事件:
var data = e.UserState as Tuple<string, string, TimeSpan>;