0

I'm trying to invoke a Form method from a different thread. In the form class, I have:

delegate int ReplaceMessageCallback(string msg, int key);

public int ReplaceMessage(string msg, int key)
{
    if (this.InvokeRequired)
    {
        ReplaceMessageCallback amc = new ReplaceMessageCallback(ReplaceMessage);
        object[] o = new object[] { msg, key };
        return (int)this.Invoke(amc, o);
    }
    bool found = false;
    int rv;

    lock (this)
    {
        if (key != 0)
        {
            found = RemoveMessage(key);
        }
        if (found)
        {
            rv = AddMessage(msg, key);
        }
        else
        {
            rv = AddMessage(msg);
        }
    }

    MainForm.EventLogInstance.WriteEntry((found) 
                        ? EventLogEntryType.Information 
                        : EventLogEntryType.Warning,
            IntEventLogIdent.MessageFormReplace1,
            String.Format("MessageForm::ReplaceMessage(({2},{0}) returns {1}.\n\n(The message {3} exist to be replaced.)",
                key,
                rv,
                msg,
                (found) 
                    ? "did" 
                    : "did not"));
    return rv;
}

When I run this, I get an exception "FormatException was unhandled" "Index (zero based) must be greater than or equal to zero and less than the size of the argument list." on the call to Invoke.

Essentially this same code fragment works fine on class methods that only take a single parameter, so I assume I'm doing something wrong with the object array but I have no idea what.

4
  • Could you post the code that uses the key variable? Commented Jul 25, 2013 at 17:42
  • 1
    Well heck. It never occurred to me that the "Invoke" would be passing along an error in the rest of the function. But that's where the error is, there's a Format in an event log that's fubar. Thanks for asking... it made me look further. Problem solved. Commented Jul 25, 2013 at 18:27
  • No problem, I see that error mostly with the String.Format call (skipping an index). Feel free to post your fix as an answer to accept it. Commented Jul 25, 2013 at 18:34
  • In the code above, I had to change {4} to {3}. (Edited above now.) I'm not that familiar with actual use of stackoverflow, not sure what "post my fix as an answer to accept it" even means to be honest. :P Commented Jul 25, 2013 at 18:48

2 Answers 2

1

An easier way to handle this is:

if (this.InvokeRequired)
{
    int rslt;
    this.Invoke((MethodInvoker) delegate
    {
        rslt = ReplaceMessage(msg, key);
    }
    return rslt;
}
Sign up to request clarification or add additional context in comments.

Comments

0

It turns out that the invoke call will pass along exceptions within the function it calls, and you can't step (F11 in debugger) into it. I assumed that it would step into the called code, so when it failed I thought it was the actual Invoke call.

I messed up a String.Format in the body of the function, and Invoke passed that exception to me with no indication of where in the code the problem actually happened.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.