How to update control in a thread safe way
I have a windows.form.userControl class and at run time i want to add some linklabels dynamically. When I apply this code snippet inside Load method it work perfectly.
for (int i = 0; i < 10; i++)
{
linkLabel = new System.Windows.Forms.LinkLabel();
linkLabel.Name = i.ToString();
linkLabel.Text = i.ToString();
linkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(linkLabel_LinkClicked);
this.Controls.Add(linkLabel);
linkLabel.Top = top;
top += 30;
}
But when I move this code snippet inside to backgroudworker doWork method it will give invalid operation exception related to cross thread issue in this line :- this.Controls.Add(linkLabel);
How do I make this as a thread safe operation? I'm newbie 开发者_如何转开发to C# and I'm using C# 4.0 using VS 2010. Thanks in advance.
You should switch to thread that created that control in order to interact with it
Use this code to fix this
if(this.InvokeRequired)
this.Invoke(new Action(() => {this.Controls.Add(linkLabel);}));
else
this.Controls.Add(linkLabel);
You have to synchronize the method to the UI thread. You can use the property Control.InvokeRequired
to check if synchronization is needed and Control.Invoke
to invoke any delegate synchronously.
private void AddLinkLabels()
{
// If synchronization is needed, i.e. when this method is called on a non-UI thread, invoke the method synchronized and return immediately.
if(InvokeRequired)
{
Invoke(new MethodInvoker(AddLinkLabels));
return;
}
for (int i = 0; i < 10; i++)
{
linkLabel = new System.Windows.Forms.LinkLabel();
linkLabel.Name = i.ToString();
linkLabel.Text = i.ToString();
linkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(linkLabel_LinkClicked);
this.Controls.Add(linkLabel);
linkLabel.Top = top;
top += 30;
}
}
The answer from Stecya can also be put into an extension method like this.
As Stecya already said: You should switch to thread that created that control in order to interact with it. This can be done in backgroundworkers ProgressChanged event, because it works in UI thread, without need to do invoke. Sample at MSDN.
精彩评论