3

在此链接的代码中: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;
 }
}
4

4 回答 4

4

TL;博士:

Control.Invoke正在您的委托上调用DynamicInvoke,它采用参数对象数组来处理任何委托类型。

//

C# 中的关键字delegate类似于指定函数指针的类型。您可以使用该类型来传递特定签名的方法。在您的示例中,签名用于采用 1 个 arg(字符串)并且不返回任何内容(void)的方法。该方法updateLabelText与该信号匹配。该行:

updateLabelTextDelegate del = new updateLabelTextDelegate(updateLabelText);

只是一种全文的说法:

updateLabelTextDelegate del = updateLabelText;

然后,您可以传递您的变量del,它现在是指向方法的updateLabelText指针Control.Invoke

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

由于paramsControl.Invoke签名中使用,您甚至不必明确地说它是object[]

label1.Invoke(del, newText);

接受一个对象数组,Invoke它将用作给定委托的参数。(是的,您的更新方法需要一个字符串 arg,请继续阅读)使用您的变量del,您可以updateLabelText自己为:

del(newText);

这基本上与以下内容相同:

updateLabelText(newText);

在内部Control.Invoke,他们正在调用您的del方法,但由于委托上的一些辅助方法,它不必知道需要多少个参数。你会发现这样的事情:

编辑我对科学做了一些深入的挖掘,内部的调用更像是:

del.DynamicInvoke(args);

args一个在哪里object[]。有关可以使用委托变量(Delegate 类型)执行的操作的更多信息,请在此处阅读更多信息。

于 2012-04-20T20:44:35.413 回答
3

如果您查看Control.Invoke的方法签名,您会发现它需要params Object[] args. 您可以传递object[] args或单个参数。

于 2012-04-20T20:47:27.500 回答
2

对象数组被传递给委托的Invoke方法。在这种情况下updateLabelTextDelegate,采用单个string参数,因此是数组中的单个元素。

事实上,数组不需要显式创建,并且

label1.Invoke(del, newText)

也是有效的。

于 2012-04-20T20:46:07.030 回答
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[]是允许各种情况的最佳方式。

于 2012-04-20T20:46:57.100 回答