4

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

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

公共部分类 Form1 : Form { public Form1() { InitializeComponent();

        Shown += new EventHandler(Form1_Shown);

        // To report progress from the background worker we need to set this property
        backgroundWorker1.WorkerReportsProgress = true;
        // This event will be raised on the worker thread when the worker starts
        backgroundWorker1.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
        // This event will be raised when we call ReportProgress
        backgroundWorker1.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    void Form1_Shown(object sender, EventArgs e)
    {
        // Start the background worker
        backgroundWorker1.RunWorkerAsync();
    }


    // 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++)
        {
            label1.Text = "Trade" + 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
    void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        // The progress percentage is a property of e
        progressBar1.Value = e.ProgressPercentage;
    }

}

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

跨线程操作无效:控件“label1”从创建它的线程以外的线程访问。

如何更新 label1 的文本

4

3 回答 3

7

在您的进度处理程序中而不是在工作线程中更新您的标签。

// 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);
 } 
于 2012-09-27T09:54:34.353 回答
5

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

label1.BeginInvoke(delegate { label1.Text = "Trade" + i; });
于 2012-09-27T09:51:11.237 回答
1

backgroundWorker1_DoWork运行在与主 UI 线程不同的线程上。

所以当你打电话时:

label1.Text = "Trade" + i;

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

于 2012-09-27T09:49:51.567 回答