日期:2014-05-17  浏览次数:21177 次

C#使用BackgroundWorker出现线程间操作无效的问题
想要达到的目的:
一个窗体(mainform)上有一个datagridview1,要把其中的数据导出到excel中,加一个按钮(But1),一点按弹即开始导出操作,并弹出一个窗体(frm)提示正在导出,显示一个进度条。
使用的方法:
加一个BackgroundWorker:work1
写一个执行导出操作的方法:daochubaozhangdan(),在这个方法中使用了mainform中的控件datagridview1

按钮But1的响应:
  private void But1_Click(object sender, EventArgs e)
  {
  work1.WorkerReportsProgress = true;
  work1.DoWork += new System.ComponentModel.DoWorkEventHandler(work1_DoWork);
  work1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(work1_ProgressChanged);
  work1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(work1_RunWorkerCompleted);
  work1.RunWorkerAsync();
  frm.ShowDialog();
  }


  private void work1_DoWork(object sender, DoWorkEventArgs e)
  {
  daochubaozhangdan(); 
  }

  private void work1_ProgressChanged(object sender, ProgressChangedEventArgs e)
  {
  frm.ProgressValue = e.ProgressPercentage;
  }

  private void work1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  {
  frm.Close();
  MessageBox.Show("导出完成", "提示");
  }

出现的问题:执行到daochubaozhangdan()需要读取datagridview1的内容时出现:线程间操作无效: 从不是创建控件“datagridview1”的线程访问它。
请问应该如何解决这个问题?
另外如果在mainform的InitializeComponent()后加上CheckForIllegalCrossThreadCalls = false则进入死循环但不进入daochubaozhangdan()方法,何解?

------解决方案--------------------
不能直接操作主线程的组件,使用invoke
------解决方案--------------------
可以加个属性,在Load事件中,是:
C# code

Control.CheckForIllegalCrossThreadCalls = false;

------解决方案--------------------
不能直接操作主线程的组件,使用invoke判断是否跨线程,使用代理调用方法