- Click Button
- Show label1
- Show label2
- Call function to parse a string the user entered before (this can take awhile depending on the string)
- Show listBox1 and progressBar1
- backgroundWorker1.RunWorkerAsync
- backgroundWorker1_DoWork() does something x number of times and reports progress each time
- backgroundWorker1_ProgressChanged() updates progressBar1 and adds an item to listBox1
- backgroundWorker1_RunWorkCompleted() shows a message Box saying “DONE”
但这不是实际发生的事情.当我浏览代码并查看表单时,它有几个问题.
> label1和label2直到解析完成后才真正出现.
> progressBar1有时会在调用ProgressChanged时更新.其他时候它将等到“DONE”打印完毕并立即更新.
>每次调用progressChange()时,listBox1上的垂直滚动条变小,以便我可以判断正在添加项目,但是在打印“DONE”之后才会显示Items的文本.
我是使用backgroundWorker的新手,所以我可能无法理解它应该如何运作.但显示标签的延迟我根本就不明白.当我浏览代码时,没有错误,并且行似乎以正确的顺序执行.
有没有人对可能导致这些问题的原因有所了解?我将不胜感激任何帮助或建议.我宁愿不发布我的代码,只是因为有很多,但如果有人需要它来更好地理解,只需lmk.
编辑:这是代码.
private void button1_Click(object sender,EventArgs e){ label1.Show(); label2.Show(); String errMsg = parseString(); if (errMsg == ""){ listBox1.Items.Clear(); listBox1.Show(); progressBar1.Maximum = 100; progressBar1.Step = 1; progressBar1.Value = 0; progressBar1.Show(); backgroundWorker1.DoWork += backgroundWorker1_DoWork; backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged; backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted; backgroundWorker1.WorkerReportsProgress = true; backgroundWorker1.WorkerSupportsCancellation = true; if (backgroundWorker1.IsBusy != true) { backgroundWorker1.RunWorkerAsync(); } } } private void backgroundWorker1_DoWork(object sender,DoWorkEventArgs e) { backgroundWorker1.ReportProgress(1,"Updating Devices"); for (int i = 0; i < 100; i++) { //todo: do stuff //update progress backgroundWorker1.ReportProgress(i,"Device:" + i); } } private void backgroundWorker1_ProgressChanged(object sender,ProgressChangedEventArgs e) { progressBar1.Value = e.Progresspercentage; listBox1.Items.Add(e.UserState); } private void backgroundWorker1_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e) { MessageBox.Show("DONE"); }
解决方法
最后我决定做两个后台工作者来解决label1和label2的问题,直到解析完成后才出现.我使用第一个进行解析,第二个使用“do stuff”部分.在代码中,您将看到我必须使用Invoke来编辑标签,因为该部分现在存在于不同的线程上.
我也意识到在调用ProgressChanged之前“做东西”不是立竿见影的.我一直在开发并且尚未实现该代码,但我知道这些操作至少需要3秒才能完成(部分原因是涉及ping).所以现在我已经在该循环中调用Sleep(3000)来模拟它的实际行为.这解决了由吃掉所有内存引起的奇怪的progressbar1和listBox1行为.
以下是代码的结果:
private void button1_Click(object sender,EventArgs e) { if (backgroundWorker1.IsBusy != true) { backgroundWorker1.RunWorkerAsync(); } } private void backgroundWorker1_DoWork(object sender,DoWorkEventArgs e) { String errMsg = parseString(); if (errMsg == "") { if (listBox1.Invokerequired) { listBox1.Invoke(new MethodInvoker(delegate { listBox1.Items.Clear(); listBox1.Show(); })); } if (progressBar1.Invokerequired) { progressBar1.Invoke(new MethodInvoker(delegate { progressBar1.Maximum = 100; progressBar1.Step = 1; progressBar1.Value = 0; progressBar1.Show(); })); } if (backgroundWorker2.IsBusy != true) { backgroundWorker2.RunWorkerAsync(); } } else { MessageBox.Show(errMsg); } } private void backgroundWorker2_DoWork(object sender,DoWorkEventArgs e) { backgroundWorker2.ReportProgress(1,"Updating Devices"); for (int i = 0; i < 100; i++) { System.Threading.Thread.Sleep(3000); //do stuff backgroundWorker2.ReportProgress(i,"Device:" + i); } } private void backgroundWorker2_ProgressChanged(object sender,ProgressChangedEventArgs e) { if (progressBar1.Invokerequired) { progressBar1.Invoke(new MethodInvoker(delegate { progressBar1.Value = e.Progresspercentage; })); } if (listBox1.Invokerequired) { listBox1.Invoke(new MethodInvoker(delegate { listBox1.Items.Add(e.UserState); })); } } private void backgroundWorker2_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e) { MessageBox.Show("DONE"); }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。