2011-05-21 36 views
1

我有不同的線程此代碼:如何在C#中的「BeginInvoke」委託函數中設置變量的值?

string sub = ""; 

this.BeginInvoke((Action)(delegate() 
{ 
    try 
    { 
     sub = LISTVIEW.Items[x].Text.Trim(); 
    } 
    catch 
    { 

    } 
})); 

MessageBox.Show(sub); 

我要的是得到的「LISTVIEW.Items[x].Text.Trim();」的值,並將它傳遞到「分」。請注意,LISTVIEW控件位於主線程中。現在我怎麼能做到這一點?

enter code here 

回答

2
 Func<string> foo =() => 
      { 
       try 
       { 
        return LISTVIEW.Items[x].Text.Trim(); 
       } 
       catch 
       { 
        // this is the diaper anti-pattern... fix it by adding logging and/or making the code in the try block not throw 
        return String.Empty; 

       } 
      }; 

     var ar = this.BeginInvoke(foo); 

     string sub = (string)this.EndInvoke(ar); 

你,當然,需要小心一點與EndInvoke會,因爲它可能會導致死鎖。

如果你願意委託語法,你也可以改變

this.BeginInvoke((Action)(delegate() 

this.BeginInvoke((Func<String>)(delegate() 

你stll需要從所有分支返回的東西,並呼籲結束時調用。

+0

lambda語法只是創建委託的更好方法。所以它仍然是一個代表。 – Yaur 2011-05-21 18:56:27

+0

@ ermac2014你可以。這是一點紅鯡魚。重要的是要注意BeginInvoke中的代碼是* asynchronous wrt。呼叫者,召集者*。在帖子中設置變量(使用適當的線程可見性控制)將會工作......但它只會在EndInvoke之後被*保證*。從[BeginInvoke](http://msdn.microsoft.com/zh-cn/library/system.windows.forms.control.begininvoke.aspx):「在創建控件的基礎句柄的線程上異步執行代理「。 – 2011-05-21 18:57:07

+0

+1「尿布反模式」是一個很好的接觸;-) – 2011-05-21 18:58:04