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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12618575/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 23:54:26  来源:igfitidea点击:

Cross-thread operation not valid: Control 'label1' accessed from a thread other than the thread it was created on

c#winformsprogress-bar

提问by nitendra jain

Possible Duplicate:
Why am I getting this error:“Cross-thread operation not valid: Control lbFolders accessed from a thread other than the thread it was created on.”?

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

I am new in winforms.In my code I am updating progress bar with for loop and now I need to update a Label in the form the loop count as shown below -

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

public partial class 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;
    }

}

公共部分类 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;
    }

}

but while accessing label1,it is throwing error -

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

Cross-thread operation not valid: Control 'label1' accessed from a thread other than the thread it was created on.

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

How can I update text of label1

如何更新 label1 的文本

采纳答案by Richard Friend

Update your label in your progress handler instead of inside the worker thread.

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

// 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);
 } 

回答by kzhen

The backgroundWorker1_DoWorkruns on a separate thread from the main UI thread.

backgroundWorker1_DoWork从主UI线程独立的线程中运行。

So when you call:

所以当你打电话时:

label1.Text = "Trade" + i;

inside backgroundWorker1_DoWork your application will throw the Cross-thread exception, because you're reporting the progress of your worker you can update the label1.Text value in the backgroundWorker1_ProgressChangedmethod

里面backgroundWorker1_DoWork您的应用程序将引发跨线程异常,因为你要举报你的工人的进步,你可以更新的label1.Text值backgroundWorker1_ProgressChanged的方法

回答by Cheng Chen

You can only access the control from the thread where it was created(that is, the UI thread). In other threads(like your BackgroundWorker), you need to use Control.BeginInvoke.

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

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