0

使用 BeginInvoke() 时出现 ArgumentException 和 TargetParameterCountException。

1) 在第一次调用时,它给出 System.ArgumentException:“System.String”类型的对象无法转换为“System.Object[]”类型。

2) 在第二次调用中,它给出 Gives TargetParameterCountException: {"Parameter count mismatch."}

为什么会这样?

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

4

1 回答 1

1

好的......有一个更完整的例子,很容易看到发生了什么。

问题是委托需要一个必须是对象数组的参数。

现在看看你是如何调用它的:

private void ChangeDay(Delegate del, params object[] args)
{
    if (this.InvokeRequired)
    {
        methodDelegate = del;
        this.BeginInvoke(new VoidDelegate(RouterDelegate), args);
    }
}

这里应该是一个参数args数组......其中的多个。因此,如果您的委托采用两个字符串参数,您将有一个长度为 2 的一个,其中每个元素都是一个字符串引用。object[]

所以你想要的是一个object[]长度为 1 的,它的唯一元素是对另一个的引用object[]。您可以轻松地做到这一点:

this.BeginInvoke(new VoidDelegate(RouterDelegate), new object[] { args });

和同样的事情RouterDelegate

methodDelegate.DynamicInvoke(new object[] { args });

到那时,我相信一切都会正常工作(就委托调用而言——您应该在 UI 线程中休眠,但那是另一回事)。

于 2012-12-14T07:05:50.493 回答