Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用多个参数调用控件时参数计数不匹配_C#_Delegates_Invoke_Multithreading - Fatal编程技术网

C# 使用多个参数调用控件时参数计数不匹配

C# 使用多个参数调用控件时参数计数不匹配,c#,delegates,invoke,multithreading,C#,Delegates,Invoke,Multithreading,我使用线程在机器上执行一些进程。最后,在另一个线程中报告进度。为了使用流程状态更新GUI,我使用如下委托: public delegate void UpdateProgressDelegate(string description, int scriptnumber); public void UpdateProgress(string description, int scriptnumber) { if (treeView.InvokeRequired) { tre

我使用线程在机器上执行一些进程。最后,在另一个线程中报告进度。为了使用流程状态更新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
}
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("Ready", 3);
调用调用时,我得到一个TargetParameterCountException:参数计数不匹配。 我想我可以通过在单个对象中放置字符串和int参数来解决这个问题,如下所示:

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
}
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。有没有办法解决这个问题?提前谢谢

这应该有效:

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
}
这应该起作用:

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
}

我会说:用简单的方法做:

treeView.Invoke((MethodInvoker)delegate {
    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
)。

我想说:用简单的方法:

treeView.Invoke((MethodInvoker)delegate {
    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
)。

AddScript方法是如何声明的?或者你只是在上面的代码中将UpdateProgress和AddScript混淆了?@Thomasleveque哎呀,我把它们混淆了,AddScript是一个完全不同的函数!我将更新我的帖子,问题和异常仍然相同。@Tigran scriptnumber是一个整数,我将更新我的帖子。AddScript方法是如何声明的?或者你只是在上面的代码中将UpdateProgress和AddScript混淆了?@Thomasleveque哎呀,我把它们混淆了,AddScript是一个完全不同的函数!我将更新我的帖子,问题和异常仍然是相同的。@Tigran scriptnumber是一个整数,我将更新我的帖子。啊,这就是为什么!但是,除了性能之外,使用您的解决方案而不是Thomas给出的解决方案(通过使用委托函数)是否有优势?还是只有两种方法可以达到同样的效果?@Carlito,如果你的意思是“与双重包装(即我答案底部的位)相比”),这将与更具体的代表方法相同;如果您的意思是“与匿名方法相比”(即我答案顶部的位),那么:编译器的静态类型检查!它不会让你使用无效的参数,等等。它还避免了一个令人困惑的额外委托类型的需要。好的,谢谢你帮助我。我接受了你的回答!啊,这就是为什么!但是,除了性能之外,使用您的解决方案而不是Thomas给出的解决方案(通过使用委托函数)是否有优势?还是只有两种方法可以达到同样的效果?@Carlito,如果你的意思是“与双重包装(即我答案底部的位)相比”),这将与更具体的代表方法相同;如果您的意思是“与匿名方法相比”(即我答案顶部的位),那么:编译器的静态类型检查!它不会让你使用无效的参数,等等。它还避免了一个令人困惑的额外委托类型的需要。好的,谢谢你帮助我。我接受了你的回答!