Raise an event in one thread to call methods in a second thread

I am working on a program that responds to events coming from an Internet socket, and possibly from timers. It seems natural to use two threads:

  • One for the main program
  • The second, which listens on the socket, analyzes the input and raises the corresponding event.

Additional requirements:

  • The application should not rely on the user interface thread (it can be launched as a console application).
  • The main program should process messages synchronously, i.e. in the order in which they arrived.
  • The main thread should not be blocked while waiting for timers (I think this means that I have to start timers on different threads).

And now for some questions :-):

  • I assume requirement # 1 means that I don't have a built-in message pump, so I cannot use Invoke() from socket listener / timer threads. Is it correct?
  • How can I safely create events in one thread (for example, a listener), and subscribers execute synchronously on another (main thread)?
  • It is very likely that new events will be raised before the completion of the subsequent handler. What will happen in this case? Will some event be polished somewhere in the CLR or will it be ignored?

Last but not least, I assume that I am aiming for parallel for the Producer / Consumer paradigm, but instead of messages I want to use events. Do you think there is a better approach?

Thanks,

Boaz

EDIT

I want to explain my motivation for using events in the first place. The application is an automatic trading mechanism that should respond to events that occur in the market (for example, a change in the price of a stock). When this happens, there may be several subscribers in the main thread that need to be called, which is the classic scenario for using events.

I think that I can always use Producer / Consumer with some message queue, and you have consumption increase events in the main thread, but I thought there might be a more direct way.

+4
source share
2 answers

I think using posts will be the easiest way. If you use C # 4, it is very simple thanks to BlockingCollection <>

So you have a generic BlockingCollection, where Message is your message class.

Then in the workflow you do this

 var msgEnum = blockingCollection.GetConsumingEnumerable(); //Per thread foreach( Message message in msgEnum ) { //Process messages here } 

That's all.

The GetConsumingEnumerable () function will block until the message is processed. Then it will remove the message from the queue and your loop will process it.

What is nice about this is that you can add more threads, and each of them has only a foreach loop.

When you're done, call blockingCollection.CompletedAdding ();

The BTW queue processes concurrency and will send messages to the queue simultaneously, etc.

Hope this helps

Andre

+4
source

You can implement a shared queue between your threads. Whenever an event occurs, you can click it in the queue. The main thread is an endless loop that checks for new events, removes them from the queue, processes the event, and when there are no more events that it has been sleeping for some time.

+2
source

All Articles