我有一个windows.form.userControl类,在运行时我想动态添加一些链接标签。当我在Load方法中应用此代码片段时,它完美地工作。
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;
}
但是当我将此代码段移到 backgroudworker doWork 方法时,它会给出无效的操作异常在这一行中交叉线程问题: - this.Controls.Add(linkLabel);
如何将其作为线程安全操作?我是C#的新手,我正在使用VS 2010使用C#4.0。 提前谢谢。
答案 0 :(得分:6)
您应切换到创建该控件的线程以便与其进行交互
使用此代码修复此
if(this.InvokeRequired)
this.Invoke(new Action(() => {this.Controls.Add(linkLabel);}));
else
this.Controls.Add(linkLabel);
答案 1 :(得分:3)
您必须将方法同步到UI线程。您可以使用属性Control.InvokeRequired
检查是否需要同步,并Control.Invoke
同步调用任何委托。
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;
}
}
答案 2 :(得分:1)
Stecya的答案也可以放入an extension method like this。
答案 3 :(得分:0)
正如Stecya已经说过:你应该切换到创建该控件的线程以便与之交互。这可以在backgroundworkers ProgressChanged事件中完成,因为它在UI线程中工作,而不需要调用。以MSDN为样本。