How to raise an event in UI thread?

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()?
 
A

AlexS

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

Sin Jeong-hun

Thank you for your reply.
It is impossible? Then I have to create many delegates in the form.
 
M

Marc Bartsch

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

Peter Duniho

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

Similar Threads


Top