我使用线程在机器上执行某些进程。最终,进度报告在另一个线程中。要使用进程的状态更新GUI,我使用如下代理:
public delegate void UpdateProgressDelegate(string description, int scriptnumber);
public void UpdateProgress(string description, int scriptnumber) {
if (treeView.InvokeRequired) {
treeView.Invoke(new UpdateProgressDelegate(UpdateProgress), description, scriptnumber);
return;
}
// Update the treeview
}
为了调用这个代表我使用:
form.UpdateProgress("Ready", 3);
调用Invoke时,我得到一个TargetParameterCountException:参数计数不匹配。 我想我可以通过将string和int参数放在一个像这样的对象中来解决这个问题:
public delegate void UpdateProgressDelegate(object[] updateinfo);
public void UpdateProgress(object[] updateinfo) {
string description = (string) updateinfo[0];
int scriptnumber = (int) updateinfo[1];
if (treeView.InvokeRequired) {
treeView.Invoke(new UpdateProgressDelegate(UpdateProgress), new object[] { description, scriptnumber });
return;
}
// Update the treeview
}
我称之为:
form.UpdateProgress(new object[] {"Ready", 3});
但这也不起作用。我一直得到相同的TargetParameterCountException。我有什么想法可以解决这个问题?提前谢谢!
答案 0 :(得分:2)
这应该有效:
public delegate void UpdateProgressDelegate(string description, int scriptnumber);
public void UpdateProgress(string description, int scriptnumber) {
if (treeView.InvokeRequired) {
treeView.Invoke(new UpdateProgressDelegate(UpdateProgress), new object[] { description, scriptnumber });
return;
}
// Update the treeview
}
答案 1 :(得分:2)
我会说:做到这一点很简单:
treeView.Invoke((MethodInvoker)delegate {
UpdateProgress(description, scriptnumber);
});
或(同样):
treeView.Invoke((MethodInvoker) () => UpdateProgress(description, scriptnumber));
这使您可以在编译器中进行静态检查,并明确检查IIRC MethodInvoker
,并使用Invoke()
而不是DynamicInvoke()
进行调用,使其更快。
为什么它不起作用;在您的示例中:
public delegate void UpdateProgressDelegate(object[] updateinfo);
你实际上传递了两个参数;要消除歧义并将单个数组传递给params
,您需要对其进行双重包装:
treeView.Invoke(new UpdateProgressDelegate(UpdateProgress),
new object[] { new object[] {description, scriptnumber }});
基本上,外部数组是所有参数"的数组,它包含一个单独的元素,这是我们要作为第一个参数传递的数组({{1 }})。