2016-06-06 21 views
0

我的意思是在backgroundworker中,我可以点击其他控件在backgroundworker工作时使用其他控件。但是,一旦我试图更新ui listView控件它正在更新,但一切都冻结/卡住,我不能点击并使用任何其他控件,直到backgroundworker完成工作。当报告进度和更新ui listView控件时,整个程序卡住了,我不能点击其他按钮,为什么?

int countUploadMsg = 0; 
     private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e) 
     { 
      MimeKit.HeaderList loaded = new MimeKit.HeaderList(); 
      List<string> test = new List<string>(); 
      int counter = 0; 
      MimekitallLoadedMessages = new List<MimeKit.MimeMessage>(); 
      MimeKit.MimeMessage loadedMessage = null; 

      for (int i = 0; i < files.Length; i++) 
      { 
       string uid = seenUids[0]; 
       loadedMessage = MimeKit.MimeMessage.Load(files[i].FullName); 
       downloaded.Add(seenUids[i]); 
       counter += 1; 
       int nProgress = counter * 100/files.Length; 
       backgroundWorker2.ReportProgress(nProgress, loadedMessage); 
      } 
     } 

的progresschanged事件

private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 
      pbt1.Value = e.ProgressPercentage; 
      pbt1.Text = e.ProgressPercentage.ToString() + "%"; 
      pbt1.Invalidate(); 
      label9.Text = countUploadMsg.ToString(); 
      label9.Visible = true; 
      MimeKit.MimeMessage Msg = e.UserState as MimeKit.MimeMessage; 
      ListViewCostumControl.lvnf.Items.Add(Msg.ToString()); 
     } 

没有我尝试到目前为止什么?我在1分钟后添加了Sleep,然后在ReportProgress行之后的dowork事件中将其更改为50ms。当把睡眠设置为50ms时,它工作正常,但后来非常缓慢。

我还尝试更新doweting事件中的MimekitallLoadedMessages列表,将其加载到loadedMessage中,然后将MimekitallLoadedMessages列表报告给e.UserState,或者只是使用List更新progressChanged事件中的listView。

试图在progressChanged中添加1ms的睡眠。

到目前为止,只有睡眠时间为50毫秒,但后来变得非常缓慢。

我试着用少量的文件,我在dowcur中的文件循环改变了。长到1000甚至到500和同样的问题。

即使将睡眠设置为50ms,并非所有时间都能正常工作。

MimeKit是一个电子邮件lib如果它在所有问题:

MimeKit

回答

-1

我认为这是多线程的面向对象编程的约束。您只能从负责它们的线程中更新UI元素:UI线程。我认为通常winforms会抛出一个异常,你可能已经禁用了某些功能或被try/catch包装捕获。

这个SO问题的答案可能是你想要进入的方向,但可能会有更清晰的语法来适合你的情况。 https://stackoverflow.com/a/15759745

而且从这个链接到谷歌的搜索结果检查出任何结果:

https://www.google.com/#q=c%23+winforms+backgroundworker+update+ui

编辑:更多信息通常最好是; J ...的答案在OP的问题上可能是正确的。我没有意识到BackgroundWorker的ProgressChanged EH不是由BackgroundWorker的线程处理的。也许仔细检查一下DoWork是不是抛出异常,并且从UI线程调用BW(回避鹅)。艺术上backgroundworkers的状态: https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.110).aspx

+2

这是没有问题的。 OP在'ProgressChanged'处理程序做UI更新,并引发此事件创建了'BackgroundWorker'的线程上(即:UI线程)。 –

4

的问题是,你正在做你的ProgressChanged处理更多的工作比你在后台线程。工作线程产生的事件比主线程能够处理它们的速度快了ProgressChanged

您可以使用StopwatchDoWork for循环中的方法块以及ProgressChanged处理程序中的方法块进行计时。

你必须在这里重新考虑你的方法 - 将需要策略的改变。

+1

这应该是被接受的答案。 – Maarten

相关问题