Connecting Tech Pros Worldwide Forums | Help | Site Map

How to raise an event in UI thread?

Sin Jeong-hun
Guest
 
Posts: n/a
#1: Aug 11 '07
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()?


Marc Bartsch
Guest
 
Posts: n/a
#2: Aug 11 '07

re: How to raise an event in UI thread?


Hi Sin,

Sin Jeong-hun wrote:
Quote:
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.
Peter Duniho
Guest
 
Posts: n/a
#3: Aug 11 '07

re: How to raise an event in UI thread?


Marc Bartsch wrote:
Quote:
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
Closed Thread