2012-04-20 100 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或单个参数。