mingpepe
mingpepe

Reputation: 579

Cross thread invoke exception

In order to change a control by another thread, I need to invoke a delegate to change the control However, it is throwing a TargetParameterCountException:

private void MethodParamIsObjectArray(object[] o) {}
private void MethodParamIsIntArray(int[] o) {}

private void button1_Click(object sender, EventArgs e)
{
        // This will throw a System.Reflection.TargetParameterCountException exception
        Invoke(new Action<object[]>(MethodParamIsObjectArray), new object[] { });
        // It works
        Invoke(new Action<int[]>(MethodParamIsIntArray), new int[] { });
}

Why does invoking with MethodParamIsObjectArray throw an exception?

Upvotes: 2

Views: 408

Answers (2)

Brett Wolfington
Brett Wolfington

Reputation: 6627

This is due to the fact that the Invoke method has a signature of:

object Invoke(Delegate method, params object[] args)

The params keyword in front of the args parameter indicates that this method can take a variable number of objects as parameters. When you supply an array of objects, it is functionally equivalent to passing multiple comma-separated objects. The following two lines are functionally equivalent:

Invoke(new Action<object[]>(MethodParamIsObjectArray), new object[] { 3, "test" });
Invoke(new Action<object[]>(MethodParamIsObjectArray), 3, "test");

The proper way to pass an object array into Invoke would be to cast the array to type Object:

Invoke(new Action<object[]>(MethodParamIsObjectArray), (object)new object[] { 3, "test" });

Upvotes: 4

toddmo
toddmo

Reputation: 22466

Invoke expects an array of objects containing the parameter values.

In the first call, you aren't providing any values. You need one value, which confusingly needs to be an object array itself.

new object[] { new object[] { }  }

In the second case, you need an array of objects containing an array of integers.

new object[] { new int[] { }  }

Upvotes: 0

Related Questions