首页 文章

跨线程操作无效:从[重复]创建的线程以外的线程访问控制'label1'

提问于
浏览
1

可能重复:为什么我收到此错误:“跨线程操作无效:控制从其创建的线程以外的线程访问的lbFolders . ”?

我是winforms的新手 . 在我的代码中,我用for循环更新进度条,现在我需要以循环计数的形式更新Label,如下所示 -

public partial class Form1:Form {public Form1(){InitializeComponent();显示= new EventHandler(Form1_Shown);

//要报告后台工作程序的进度,我们需要设置此属性
backgroundWorker1.WorkerReportsProgress = true;
//当工作程序启动时,将在工作线程上引发此事件
backgroundWorker1.DoWork = new DoWorkEventHandler(backgroundWorker1_DoWork);
//当我们调用ReportProgress时,将引发此事件
backgroundWorker1.ProgressChanged = new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
}

private void Form1_Load(object sender,EventArgs e)
{

}

void Form1_Shown(object sender,EventArgs e)
{
//启动后台工作程序
backgroundWorker1.RunWorkerAsync();
}

//在工作线程上做我们的事情!
void backgroundWorker1_DoWork(对象发送者,DoWorkEventArgs e)
{
//你的后台任务就在这里
for(int i = 0; i <= 100; i)
{
label1.Text =“交易”i;
//向'UI'线程报告进度
backgroundWorker1.ReportProgress(ⅰ);
//模拟长任务
System.Threading.Thread.Sleep(100);
}
}
//返回'UI'线程,以便我们可以更新进度条
void backgroundWorker1_ProgressChanged(object sender,ProgressChangedEventArgs e)
{
//进度百分比是e的属性
progressBar1.Value = e.ProgressPercentage;
}

}

但是在访问label1时,它会抛出错误 -

跨线程操作无效:控制'label1'从其创建的线程以外的线程访问 .

如何更新label1的文本

3 回答

  • 0

    在进度处理程序中而不是在工作线程内更新标签 .

    // On worker thread so do our thing! 
     void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 
         // Your background task goes here 
         for (int i = 0; i <= 100; i++) 
         { 
             // Report progress to 'UI' thread 
             backgroundWorker1.ReportProgress(i); 
             // Simulate long task 
             System.Threading.Thread.Sleep(100); 
         } 
     } 
     // Back on the 'UI' thread so we can update the progress bar - and our label :)
     void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
     { 
         // The progress percentage is a property of e 
         progressBar1.Value = e.ProgressPercentage; 
         label1.Text = String.Format("Trade{0}",e.ProgressPercentage);
     }
    
  • 4

    您只能从创建它的线程(即UI线程)访问该控件 . 在其他线程(如BackgroundWorker)中,您需要使用Control.BeginInvoke .

    label1.BeginInvoke(delegate { label1.Text = "Trade" + i; });
    
  • 2

    backgroundWorker1_DoWork 在主UI线程的单独线程上运行 .

    所以当你打电话时:

    label1.Text = "Trade" + i;
    

    在backgroundWorker1_DoWork内部,您的应用程序将抛出跨线程异常,因为您正在报告工作进度,您可以更新 backgroundWorker1_ProgressChanged 方法中的label1.Text值

相关问题