我怎样才能更新listView或标签和报告backgroundworker进度更改而不使用invoke?

问题描述:

我不确定invoke是否正确使用它。它工作正常,但我想知道如果我应该使用invoke或其他方式来更新gui控件?如果我想报告更多的1个GUI控件?我怎样才能更新listView或标签和报告backgroundworker进度更改而不使用invoke?

现在我正在使用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方法发送信息给用户界面和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一个thesecond。如果你想发送信息丰富,插入这种说法您的自定义对象或任何其他现有的具有所需性能,并在另一边 - 在ProgressChanged事件,再次“投”,它为适当的类型,例如:

ReportProgress

backgroundWorker1.ReportProgress(countfiles, Tuple.Create(currFile, "Copying...", timeRem)); 

ProgressChanged事件:

var data = e.UserState as Tuple<string, string, TimeSpan>;