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
Cross-thread operation not valid: Control 'label1' accessed from a thread other than the thread it was created on
提问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.”?
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; });

