views:

214

answers:

3

Raising events in multithreaded classes?

I am running a class(gamepad handler) that uses many child threads to check for key input and the like then it raises events to my form to sort out the needed reaction, Is there a way to make the event raises on the same thread as the class itself.

A: 

Do you mean, raise event on the main thread and not the child thread? If so then the correct way to do this would be queue the event into the main thread and let main thread process the queue. Essentially the main thread need to be written to work off the queue. A classic example if the something like this is the message processing in a windows ui thread.

If this is same as your case, then you should send a message to UI message pump.

Preet Sangha
+3  A: 

The simpliest answer is, "just raise the event on the current thread." It is up to the form to handle the events then perform any updates on the form's thread using Control.Invoke.

Here is the recommended way to update a Label control called __message from another thread.

Add the following code to the form.

Delegate Sub SetTextDelegate(ByVal message As String)

Public Sub SetText(ByVal message As String)
    If __message.InvokeRequired Then
        Dim oCall As New SetTextDelegate(AddressOf SetText)
        Me.Invoke(oCall, New Object() {message})
    Else
        __message.Text = message
    End If
End Sub

Then call form.SetText(<messageToDisplay>) where needed.

You can either use the Control.Invoke or Control.BeginInvoke methods. See Control.InvokeRequired Property for more information.

AMissico
A: 

How to handle any event on a GUI thread when the event may have been called from another thread (sorry for the C# code but it should easily translate):

void myEventHandler(object sender, EventArgs e) 
{
    if (this.InvokeRequired) 
    { 
        this.BeginInvoke(new MethodInvoker(delegate() { myEventHandler(sender,e); }));   
        return; 
    } 

    // write code to handle event here 

}

Alternate Syntax:

if (this.InvokeRequired) 
{ 
    this.BeginInvoke((MethodInvoker)delegate
    {
       myLabel.Text = "What a great post";
    });
}
Oplopanax
the "this" doesnt appear to work,hmm and the methodinvoker wont allow that delegate format
Jim
this refers to a control; I can't see how the MethodInvoker isn't working for you, I took this from some production code. Is it a c# to VB thing?
Oplopanax
maybe it is specific to VB, but the "this" doesnt work, when dealing with the form "Me" is used, the answer appears to be if(me.invokerequired){ rerun eventhandler in form through a delegate}
Jim
right, as I said, sorry about the c#, it should easily translate.
Oplopanax