Question

I am getting ArgumentException and TargetParameterCountException when using BeginInvoke().

1) In first call it gives System.ArgumentException: Object of type 'System.String' cannot be converted to type 'System.Object[]'.

2) In second call it gives Gives TargetParameterCountException: {"Parameter count mismatch."}

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. My sincere apologies for the old wrongly framed question. I am usually not this careless. Please also ignore language syntax errors if any.

Was it helpful?

Solution

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. 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.

So what you want is an object[] with length 1, whose sole element is a reference to another object[]. You can do that easily:

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

and the same thing in 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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top