在此链接的代码中:http://c-sharp-programming.blogspot.com/2008/07/cross-thread-operation-not-valid.html,委托用于从工作线程更新文本框的值。
我基本上可以看到发生了什么,但这条线的语法具体是:
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 :(得分:4)
TL; DR:
Control.Invoke
在您的委托上调用DynamicInvoke,它使用一个参数对象数组来处理任何委托类型。
//
C#中的关键字delegate与指定函数指针类型无关。您可以使用类型来传递特定签名的方法。在您的示例中,签名用于获取1个arg(字符串)并且不返回任何内容(void)的方法。方法updateLabelText
与该sig匹配。这一行:
updateLabelTextDelegate del = new updateLabelTextDelegate(updateLabelText);
只是一种全文的说法:
updateLabelTextDelegate del = updateLabelText;
然后,您可以将变量del
传递给updateLabelText
方法,该变量现在是方法Control.Invoke
的指针。
label1.Invoke(del, new object[] { newText });
感谢params
在Control.Invoke
签名中使用,您甚至不必明确表示它是object[]
label1.Invoke(del, newText);
Invoke
获取一个对象数组,它将用作给定委托的args。 (是的,您的更新方法需要一个字符串arg,请继续阅读)使用变量del
,您可以自己调用updateLabelText
:
del(newText);
基本上与以下内容相同:
updateLabelText(newText);
在Control.Invoke
内,他们正在调用您的del
方法,但由于委托上的一些辅助方法,它不会知道知道需要多少args。你会发现这样的东西:
编辑我对科学进行了深入挖掘,invocation内部更像是:
del.DynamicInvoke(args);
args
是object[]
的位置。有关您可以使用委托变量(类型为委托)执行的操作的更多信息,请阅读更多here。
答案 1 :(得分:3)
如果查看Control.Invoke的方法签名,您会看到它需要params Object[] args
。您可以传递object[] args
或单个参数。
答案 2 :(得分:2)
将对象数组传递给委托的Invoke
方法。在这种情况下,updateLabelTextDelegate
采用单个string
参数,因此是数组中的单个元素。
实际上,不需要显式创建数组,并且
label1.Invoke(del, newText)
也有效。
答案 3 :(得分: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[]
的值是允许各种情况的最佳方式。