2012-04-20 77 views
3

在此鏈接的代碼中:http://c-sharp-programming.blogspot.com/2008/07/cross-thread-operation-not-valid.html,委託用於從工作線程更新文本框的值。解釋委託調用的語法c#

我基本上可以看到發生了什麼,但此行的語法明確:

label1.Invoke(del, new object[] { newText }); 

是混亂給我。有人可以解釋嗎?當只有一個參數時,爲什麼我們爲委託使用新的對象數組語法?

全碼:

delegate void updateLabelTextDelegate(string newText); 
private void updateLabelText(string newText) 
{ 
if (label1.InvokeRequired) 
{ 
    // this is worker thread 
    updateLabelTextDelegate del = new updateLabelTextDelegate(updateLabelText); 
    label1.Invoke(del, new object[] { newText }); 
} 
else 
{ 
    // this is UI thread 
    label1.Text = newText; 
} 
} 
+0

這是一個錯誤,label1.Invoke()不是委託。只要寫'label1.Invoke(del,newText);' – 2012-04-20 21:12:55

+0

他說label1.Invoke()是一個委託嗎?我沒有讀到。另外,很好的指出你可以使用一個單獨的參數,而不需要顯式對象[],這要歸功於params。 – payo 2012-04-20 21:19:06

回答

4
TL

; DR:

Control.Invoke呼籲你委託這需要的參數的對象陣列,任何委託類型工作DynamicInvoke

//

關鍵字delegate在C#中analagous到指定類型的函數指針。您可以使用類型傳遞特定簽名的方法。在你的例子中,簽名是一個方法,該方法需要1個參數(一個字符串)並且不返回任何東西(void)。方法updateLabelText匹配那個sig。行:

updateLabelTextDelegate del = new updateLabelTextDelegate(updateLabelText); 

只是說的全文方式:

updateLabelTextDelegate del = updateLabelText; 

然後,你可以通過你的變量del,現在是一個指向方法updateLabelTextControl.Invoke方法。

label1.Invoke(del, new object[] { newText }); 

這是用在Control.Invoke簽名感謝params,你甚至不必明確地說,這是一個object[]

label1.Invoke(del, newText); 

Invoke需要對象的數組,它會使用作爲代表給出的參數。 (是你的更新方法需要一個字符串ARG,請繼續閱讀)與您的變量del,你呼叫updateLabelText自己:

del(newText); 

這將基本上是一樣的:

updateLabelText(newText); 

Control.Invoke ,他們打電話給你的del方法,但它不知道有多少參數,這要歸功於代表上的一些輔助方法。你會發現這樣的事情:

編輯我做了一些深層次的挖掘科學,invocation內部更像是:

del.DynamicInvoke(args); 

argsobject[]。有關可以使用委託變量(委託類型)執行的操作的更多信息,請閱讀更多here

+0

謝謝您的詳細解答,非常感謝! :) – 2012-04-20 23:42:52

2

對象數組傳遞給代理的Invoke方法。在這種情況下,updateLabelTextDelegate只有一個參數string,因此是數組中的單個元素。

其實陣列並不需要明確創建,並

label1.Invoke(del, newText) 

也是有效的。

+0

+1沒有使用'new object []',但我會指出這只是一個選項,感謝'params' – payo 2012-04-20 21:21:42

1

首先,值得注意的是,這不是在委託上調用Invoke - 它的控件上調用Invoke。現在,如果你看看這裏所使用的Control.Invoke簽名,那就是:

public Object Invoke(
    Delegate method, 
    params Object[] args 
) 

如果方法把一個特定委託類型,它可能會採取相應的參數類型爲代表。在情況下,您的代理只需要一個參數,但假設我們想在Action<string, string, int>通 - 使用上述非常普遍的做法,我們可以做到這一點:

control.Invoke(someDelegate, new object[] { "foo", "bar", 10 }); 

所以答案是,object[]是那裏提供一般性,因爲代表類型也是一般的。這有點像MethodInfo.Invoke - 在編譯時不知道有多少參數,類型object[]的值是允許各種情況的最佳方式。

3

如果您查看Control.Invoke的方法簽名,您會發現需要params Object[] args。您可以通過object[] args或單個參數。