本文介绍了BackgroundWorker ProgressChanged System.InvalidOperationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我正在使用BackgroundWorker来处理数据并使用ProgressChanged事件更新我的UI。但是,当我尝试将ToolStripProgressBar.Visible更改为true时,我收到System.InvalidOperationException,但不确定原因。这是我的ProgressChanged事件的代码:I am using a BackgroundWorker to process data and update my UI with the ProgressChanged event. However, I get a System.InvalidOperationException when I try to change my ToolStripProgressBar.Visible to true, but not sure why. Here's my code for the ProgressChanged event:toolStripProgressBar1.Visible = true;toolStripProgressBar1.Value = e.ProgressPercentage;if (e.UserState != null) toolStripStatusLabel1.Text = e.UserState.ToString();如果我注释掉第一行,我就不会得到异常,如下所示:If I comment out the first line, I don't get the Exception, like so://toolStripProgressBar1.Visible = true;toolStripProgressBar1.Value = e.ProgressPercentage;if (e.UserState != null) toolStripStatusLabel1.Text = e.UserState.ToString(); 此外,Exception的详细信息说:Also, the details of the Exception says:Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on.我搜索的所有问题似乎都有控件的名称,而不仅仅是空引号,但我很难找到它特别。我不确定为什么我可以访问Value成员但不能访问ToolStripProgressBar的Visible成员。 更新: 我测试了一个我试图做的小样本项目并获得相同的结果。同样,如果我注释掉Visible声明,我没有任何例外。All the questions that I've searched for seem to have the name of the control, not just empty quote marks, but I'm having a hard time searching for that specifically. I'm not sure why I can access the Value member but not the Visible member of the ToolStripProgressBar.UPDATE:I tested a small sample project of what I was trying to do and get the same results. Again, if I comment out the Visible statement, I don't get any exceptions.public partial class Form1 : Form{ public Form1() { InitializeComponent(); } private void btnDoWork_Click(object sender, EventArgs e) { if (bgw.IsBusy == false) bgw.RunWorkerAsync(); } private void bgw_DoWork(object sender, DoWorkEventArgs e) { ImportData dataImporter = new ImportData(); dataImporter.ProgChanged += bgw_ProgressChanged; dataImporter.Import(); } private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e) { toolStripProgressBar1.Visible = true; // Comment line out prevents Exception toolStripProgressBar1.Value = e.ProgressPercentage; if (e.UserState != null) toolStripStatusLabel.Text = e.UserState.ToString(); } private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { toolStripProgressBar1.Visible = false; toolStripStatusLabel.Text = "Finished"; }}public class ImportData{ public ProgressChangedEventHandler ProgChanged; private void UpdateProgress(int percent, string state) { if (ProgChanged != null) ProgChanged(this, new ProgressChangedEventArgs(percent, state)); } public void Import() { UpdateProgress(100, "Work Completed"); }}推荐答案private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e){ if (InvokeRequired) { Invoke((ProgressChangedEventHandler)bgw_ProgressChanged, sender, e); return; } ...} 或者你可以添加一个额外的间接层:Or you could add an extra layer of indirection:private void bgw_DoWork(object sender, DoWorkEventArgs e){ ImportData dataImporter = new ImportData(); dataImporter.ProgChanged += imp_ProgressChanged; dataImporter.Import();}private void imp_ProgressChanged(object sender, ProgressChangedEventArgs e){ bgw.ReportProgress(e.ProgressPercentage, e.UserState);}private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e){ // Hooked up to the BackgroundWorker's ProgressChanged event. ...} 或者,您可以修改 ImportData 用于在UI线程上引发事件的类:Or, you could modify your ImportData class to raise the event on the UI thread:public class ImportData{ private readonly SendOrPostCallback _progressReporter; private AsyncOperation _asyncOperation; public ImportData() { _progressReporter = arg => OnProgChanged((ProgressChangedEventArgs)arg); } public ProgressChangedEventHandler ProgChanged; protected virtual void OnProgChanged(ProgressChangedEventArgs e) { ProgressChangedEventHandler handler = ProgChanged; if (handler != null) handler(this, e); } private void UpdateProgress(int percent, string state) { ProgressChangedEventArgs arg = new ProgressChangedEventArgs(percent, state); if (_asyncOperation != null) { _asyncOperation.Post(_progressReporter, arg); } else { OnProgChanged(arg); } } public void Import() { _asyncOperation = AsyncOperationManager.CreateOperation(null); UpdateProgress(100, "Work Completed"); }} 这篇关于BackgroundWorker ProgressChanged System.InvalidOperationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-05 22:21