简体   繁体   English

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

[英]ArgumentException, TargetParameterCountException on Control.BeginInvoke(). Why?

I am getting ArgumentException and TargetParameterCountException when using BeginInvoke(). 使用BeginInvoke()时出现ArgumentException和TargetParameterCountException。

1) In first call it gives System.ArgumentException: Object of type 'System.String' cannot be converted to type 'System.Object[]'. 1)在第一次调用中,它给出了System.ArgumentException:无法将类型为“ System.String”的对象转换为类型为“ System.Object []”。

2) In second call it gives Gives TargetParameterCountException: {"Parameter count mismatch."} 2)在第二次调用中,它给出GiveTargetParameterCountException:{“参数计数不匹配。”}

Why does it happen? 为什么会发生?

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: Corrected the wrongly framed question now. PS:现在纠正了错误构建的问题。 My sincere apologies for the old wrongly framed question. 对于陈旧的错误构架的问题,我表示由衷的歉意。 I am usually not this careless. 我通常不是这样粗心的。 Please also ignore language syntax errors if any. 如果有的话,也请忽略语言语法错误。

Okay... with a fuller example, it's reasonably easy to see what's going on. 好的,举一个完整的例子,可以很容易地看到发生了什么。

The problem is that the delegate expects a single parameter which must be an object array. 问题是委托期望单个参数必须是对象数组。

Now look at how you're invoking it: 现在看看您如何调用它:

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

The args here is expected to be an array of arguments ... multiple of them. 此处的args应该是一个参数数组...它们是多个。 So if your delegate took two string parameters, you'd have an object[] with a length of two, each of element of which would be a string reference. 因此,如果您的委托人使用了两个字符串参数,则将有一个长度为2的object[] ,其中每个元素都是一个字符串引用。

So what you want is an object[] with length 1, whose sole element is a reference to another object[] . 因此,您想要的是长度为1的object[] ,其唯一元素是对另一个object[]的引用。 You can do that easily: 您可以轻松地做到这一点:

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

and the same thing in RouterDelegate : RouterDelegate的同一件事:

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

At that point, I believe everything will work fine (in terms of delegate invocation - you should not be sleeping in the UI thread, but that's a different matter). 到那时,我相信一切都可以正常工作(就委托调用而言-您应该在UI线程中睡觉,但这是另一回事)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM