BeginInvoke calls EventHandler with different parameters than supplied

S

Sandor Heese

Question,

When using BeginInvoke (on a From to marshal to the UI thread) with the
EventHandler delegate I see some strange behaviour. The problem is that I
call the UpdateTextBox method with a class derived from EventArgs ( i.e.
MyEventArgs) and when the BeginInvoke is called and the UpdateTextBox
methode is call on the UI thread the parameter e (EventArgs) does not
contain the derived MyEventArgs object but a EventArgs object.

The strange thing is that if I create a delegate with the same signature as
the EventHandler ( MyEventHandler) everything works as expected. (See
comments in the code below)

Can anyone explane this to me?

Sandor

(Methods below are implemented on a Form derived class)

private void button1_Click(object sender, System.EventArgs e)
{
Thread t = new Thread(new ThreadStart(OnThreadStart));
t.Start();
}
private void OnThreadStart()
{
UpdateTextBox(null, new MyEventArgs(DateTime.Now.ToLongTimeString()));
}
private void UpdateTextBox(object sender, EventArgs e)
{
if(InvokeRequired)
{
// When using MyEventHandler everything works as expected.
//MyEventHandler h = new MyEventHandler(UpdateTextBox);
EventHandler h = new EventHandler(UpdateTextBox);
BeginInvoke(h, new object[] {sender, e});
}
else
{
// This cast will fail !!!!!!!!!!!!!!!!!!!!!!
MyEventArgs args = (MyEventArgs)e;
textBox1.Text = string.Format("Current time: {0}", args.CurrentTime);
}
}

public class MyEventArgs : EventArgs
{
public readonly string CurrentTime;

public MyEventArgs(string currentTime)
{
CurrentTime = currentTime;
}
}
delegate void MyEventHandler(object sender, EventArgs e);
 
J

Jon Skeet [C# MVP]

Sandor Heese said:
When using BeginInvoke (on a From to marshal to the UI thread) with the
EventHandler delegate I see some strange behaviour. The problem is that I
call the UpdateTextBox method with a class derived from EventArgs ( i.e.
MyEventArgs) and when the BeginInvoke is called and the UpdateTextBox
methode is call on the UI thread the parameter e (EventArgs) does not
contain the derived MyEventArgs object but a EventArgs object.

Yes - for some reason, if you call Invoke or BeginInvoke with an
EventHandler delegate, whatever parameters you supply will be ignored.
Bizarre, no?

It's documented for Invoke, but not BeginInvoke. Here's the docs for
Invoke:

<quote>
The delegate can be an instance of EventHandler, in which case the
sender parameter will contain this control, and the event parameter
will contain EventArgs.Empty. The delegate can also be an instance of
MethodInvoker, or any other delegate that takes a void parameter list.
A call to an EventHandler or MethodInvoker delegate will be faster than
a call to another type of delegate.
</quote>
 
S

Sandor Heese

Yes, I agree it is bizarre. (probably a performance optimalization)

Thanks Jon,

Sandor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top