3

我有一個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。 在此先感謝。

回答

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; 
    } 
} 
+0

嗨弗洛裏安,這一行'Invoke(AddLinkLabels);'給錯誤說無效論點。有關於此的任何想法?謝謝。 – 2011-05-31 05:00:21

+0

@poor_guy:我更新了我的答案 – 2011-05-31 06:15:23

+0

非凡:D非常感謝:-) – 2011-05-31 07:23:53

6

你應該切換到創建的控制,以與它交互

使用此代碼來解決這個

if(this.InvokeRequired) 
    this.Invoke(new Action(() => {this.Controls.Add(linkLabel);})); 
else 
    this.Controls.Add(linkLabel); 
+2

我會調用整個方法,因爲您的示例將導致十個調用「Control.Invoke」而不是一個。 – 2011-05-30 10:48:47

+0

這是一個優化問題。你是對的,需要避免多個Invokes – Stecya 2011-05-30 10:52:32

+0

Stecya非常感謝你:) – 2011-05-30 10:59:13

0

由於Stecya已經說過:您應該切換到創建該控件的線程才能與之交互。這可以在backgroundworkers ProgressChanged事件中完成,因爲它可以在UI線程中工作,而無需執行調用。樣品在MSDN

相關問題