如何解决如何以线程安全的方式更新控件
| 我有一个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。
提前致谢。
解决方法
您必须将方法同步到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;
}
}
, 您应该切换到创建该控件的线程才能与其进行交互
使用此代码可解决此问题
if(this.InvokeRequired)
this.Invoke(new Action(() => {this.Controls.Add(linkLabel);}));
else
this.Controls.Add(linkLabel);
, Stecya的答案也可以放入这样的扩展方法中。
, 正如Stecya所说:您应该切换到创建该控件的线程才能与其进行交互。这可以在backgroundworkers ProgressChanged事件中完成,因为它可以在UI线程中工作,而无需执行调用。在MSDN上的样本。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。