hamid
hamid

Reputation: 850

calling event that implements at other thread in C#

I have a class with a Socket, listens to clients to receive data. When receive new data I want to call an event (if implemented) but as you know every connection has its own thread so the event will run at that thread and you know the rest. you can not work with form controls. How do I call the event (or invoke it). I'm really new to thread and network programing so I appreciate any example.

public class HVremotechooser
{
    public delegate void NewOrder(Order order);
    public event NewOrder nOrder;

    //... (code elided)


    public void ReceiveCallback(IAsyncResult AsyncCall)  // new connection of client
    {

         //... (code elided)
         if (nOrder != null)
              nOrder(Order);   // calling the event "nOrder"
         //... (code elided)

    }

}

thank you.

Upvotes: 1

Views: 214

Answers (4)

Yaur
Yaur

Reputation: 7452

UI Threading is a UI concern. In my opinion you shouldn't worry about invoking to the ui thread in this code. Rather the consumer of the event should do the Invoke or whatever other threading stuff they happen to need to do. That way if the UI person needs to change their strategy (e.g. by using a timer) your non-UI related code wont need to change.

Upvotes: 0

Brian Gideon
Brian Gideon

Reputation: 48949

You can use the typical marshling operations like Invoke or BeginInvoke to inject the execution of a delegate onto the UI thread. Just pass an instance of ISynchronizeInvoke or SynchronizationContext to your class to facilitate the marshaling.

However, I would not do that in your case. Since, presumably anyway, these callbacks are occuring because of socket events it is possible likely they are coming in hard and heavy. You definitely do not want to slam your UI thread with all of that activity. Instead, package up all of the pertinent data and put into a collection that the UI thread can then poll for using a System.Windows.Forms.Timer on a more reasonable interval.

I rip on these marshling operations all of the time. They are way overrated and overused. Remember, there are two general methods of sharing data and signaling between UI and worker threads.

  • Push method via Invoke or BeginInvoke in the worker thread
  • Pull method via System.Windows.Forms.Timer in the UI thread

The pull method can be, and often is, more elegant.

Upvotes: 0

Maarten
Maarten

Reputation: 22945

If you want to update your form from a non-UI thread, you have to invoke the action. What I normally do is the following:

private void LongRunningBackgroundThread() {
   // lots of work
   ...
   // Update my form
   InvokeIfRequired(() => {
       ...update form...
   }
}

private static void InvokeIfRequired(Action a) {
    if (control.InvokeRequired) {
        control.Invoke(a);
    } else {
        a();
    }
}

See here and here

Upvotes: 1

LiquidAsh
LiquidAsh

Reputation: 271

I ran into a similar problem with a Silverlight application that I was working on last week, and used the Dispatcher.BeginInvoke method. With Windows forms, it looks like it might be easier to use Control.BeginInvoke instead (although I believe that either should work): http://msdn.microsoft.com/en-us/library/system.windows.forms.control.begininvoke.aspx

Upvotes: 0

Related Questions