使用BeginInvoke()时,我收到了ArgumentException和TargetParameterCountException。
1)在第一次调用时,它给出了System.ArgumentException:'System.String'类型的对象无法转换为'System.Object []'类型。
2)在第二次调用中,它给出了TargetParameterCountException:{“参数计数不匹配。”}
为什么会这样?
using System;
using System.Threading;
using System.Windows.Forms;
namespace BeginInvokeArgsTest
{
public partial class Form1 : Form
{
private delegate void VoidDelegate(params object[] args);
private Delegate methodDelegate;
public Form1()
{
InitializeComponent();
methodDelegate = new VoidDelegate(SetLabelDelegate);
Thread t = new Thread(ChangeDay);
t.Start();
}
private void ChangeDay()
{
//Gives ArgumentException. 'System.String' cannot be converted to type 'System.Object[]'.
ChangeDay(new VoidDelegate(SetLabelDelegate), "Sunday" );
//Gives TargetParameterCountException: {"Parameter count mismatch."}
ChangeDay(new VoidDelegate(SetLabelDelegate), "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
}
private void ChangeDay(Delegate del, params object[] args)
{
if (this.InvokeRequired)
{
methodDelegate = del;
this.BeginInvoke(new VoidDelegate(RouterDelegate), args );
}
}
private void RouterDelegate(params object[] args)
{
methodDelegate.DynamicInvoke(args);
}
private void SetLabelDelegate(params object[] args)
{
foreach (object day in args)
{
label1.Text = day as string;
Thread.Sleep(1000);
}
}
}
}
PS:现在更正了错误框架的问题。我真诚地为旧的错误框架问题道歉。我通常不会这么粗心。如果有的话,请忽略语言语法错误。
答案 0 :(得分:1)
好的......有一个更全面的例子,很容易看出发生了什么。
问题是委托需要一个必须是对象数组的参数。
现在看看你是如何调用的:
private void ChangeDay(Delegate del, params object[] args)
{
if (this.InvokeRequired)
{
methodDelegate = del;
this.BeginInvoke(new VoidDelegate(RouterDelegate), args);
}
}
这里的args
应该是一个参数的数组 ...多个。因此,如果您的委托使用了两个字符串参数,那么您将拥有一个长度为2的object[]
,其中每个元素都是一个字符串引用。
所以你想要的是长度为1的object[]
,其唯一元素是对另一个object[]
的引用。你可以轻松地做到这一点:
this.BeginInvoke(new VoidDelegate(RouterDelegate), new object[] { args });
和RouterDelegate
中的相同内容:
methodDelegate.DynamicInvoke(new object[] { args });
此时,我相信一切都会正常工作(在委托调用方面 - 你应该不在UI线程中睡觉,但这是另一回事。)