【问题标题】:Parameter count mismatch when invoking control with multiple parameters使用多个参数调用控件时参数计数不匹配
【发布时间】:2012-01-19 10:16:46
【问题描述】:

我使用线程在机器上执行某些进程。最终,进度会在另一个线程中报告。为了使用进程状态更新 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: Parameter count mismatch。 我想我可以通过将字符串和 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。有什么想法可以解决这个问题吗?提前致谢!

【问题讨论】:

  • AddScript 方法是如何声明的?还是您只是在上面的代码中将 UpdateProgress 与 AddScript 混淆了?
  • @ThomasLevesque 哎呀,我确实把他们弄糊涂了,AddScript 是一个完全不同的函数!我会更新我的帖子,问题和异常仍然相同。
  • @Tigran scriptnumber 是一个整数,我会更新我的帖子。

标签: c# delegates invoke multithreading


【解决方案1】:

我会说:做简单的方法:

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 }});

基本上,外部数组是“所有参数的数组”,它包含一个元素,这是我们不希望作为第一个参数传递的数组 (updateinfo)。

【讨论】:

  • 啊,原来如此!但是,除了性能之外,使用您的解决方案而不是 Thomas 给出的解决方案(通过使用委托函数)是否有优势?还是只有两种方法可以实现相同的目标?
  • @Carlito 如果您的意思是“与双重包装相比”(即我的答案底部的位) - 这将与更具体的委托方法相同;如果您的意思是“与匿名方法相比”(即我的答案顶部的位)-那么:编译器的静态类型检查!它不会让您使用无效参数等。它还避免了对令人困惑的额外委托类型的需要。
  • 好的,谢谢你帮助我。我接受了你的回答!
【解决方案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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 2017-10-31
    相关资源
    最近更新 更多