Control.BeginInvoke()上的ArgumentException,TargetParameterCountException。为什么?

时间:2012-12-13 11:52:42

标签: c# invoke begininvoke

使用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:现在更正了错误框架的问题。我真诚地为旧的错误框架问题道歉。我通常不会这么粗心。如果有的话,请忽略语言语法错误。

1 个答案:

答案 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线程中睡觉,但这是另一回事。)