How to raise an event in UI thread?

  • Thread starter Thread starter Sin Jeong-hun
  • Start date Start date
S

Sin Jeong-hun

Suppose class Engine do something in another thread and raise events.

class Engine
{
Thread Worker;
public event ... EngineMessage;
public void Start()
{
Worker=new Thread(new ThreadStart(Run));
Worker.Start();
}
private Run()
{
..Do some length work....
under some condition, fires
this.EngineMessage(msg);
}
}

If I subscribe to this event in the Form and tries to set the message
to a TextBox, this causes InvalidOperationExeption since this message
is from another thread. I can use this.InvokeRequred at the form, but
can't I do this at the Engine class so that at the Form, I can handle
the message without using delegates? I mean in the Engine class , can
I somehow raise the event in the same thread as the one called Start()?
 
No
You must use InvokeRequired to check if you are on proper thread.

It's a pain the specific place, but that's how controls were designed in
WinForms.

Hopefully in one of future versions all controls will do this check
automatically and re-invoke property/method code on proper thread. It's
pretty standard pattern for multithreaded apps with UI. Not sure why
WinForms designers did not think about that.
 
Thank you for your reply.
It is impossible? Then I have to create many delegates in the form.
 
Hi Sin,
Suppose class Engine do something in another thread and raise events.

class Engine
{
Thread Worker;
public event ... EngineMessage;
public void Start()
{
Worker=new Thread(new ThreadStart(Run));
Worker.Start();
}
private Run()
{
..Do some length work....
under some condition, fires
this.EngineMessage(msg);
}
}

If I subscribe to this event in the Form and tries to set the message
to a TextBox, this causes InvalidOperationExeption since this message
is from another thread. I can use this.InvokeRequred at the form, but
can't I do this at the Engine class so that at the Form, I can handle
the message without using delegates? I mean in the Engine class , can
I somehow raise the event in the same thread as the one called Start()?
I am not sure whether you can raise the event on the UI thread without a reference to the UI, but you can do the following in your form that processes the EngineMessage event without explicitly defining so many delegates:

class MyForm : Form
{
// Process EngineMessage here
protected void Engine_EngineMessage(string msg)
{
// Invoke SetText on UI thread using an anonymous method and
// cast it to MethodInvoker.
this.Invoke((MethodInvoker)delegate { SetText(msg); });
}

private void SetText(string txt)
{
this.myTextBox.Text = txt;
}
}

Hope it helps,

Marc.
 
Marc said:
I am not sure whether you can raise the event on the UI thread without a
reference to the UI, but you can do the following in your form that
processes the EngineMessage event without explicitly defining so many
delegates:

class MyForm : Form
{
// Process EngineMessage here
protected void Engine_EngineMessage(string msg)
{
// Invoke SetText on UI thread using an anonymous method and
// cast it to MethodInvoker.
this.Invoke((MethodInvoker)delegate { SetText(msg); });
}

Or, if it's really a simple method like that (it's not always, but in
this example obviously it is :) ):

// Process EngineMessage here
protected void Engine_EngineMessage(string msg)
{
// Invoke SetText on UI thread using an anonymous method and
// cast it to MethodInvoker.
this.Invoke((MethodInvoker)delegate { this.myTextBox.Text = msg });
}

Actually, for that matter, unless I needed to use the same code
somewhere else by calling it as a method, I would probably just put the
whole invoke-necessary code in the anonymous delegate. It's just that
as the anonymous delegate gets longer, the odds that it's doing
something that needs to be shared by non-invoking code goes up, thus
justifying putting it into a shareable method. :)

Pete
 

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

Back
Top