Raise event in one thread to invoke methods in a second thread - c#

I'm working on a program which reacts to events coming from an internet socket, and possibly from timers as well. It seems natural to use two threads:
One for the main program
A second one which listens to the socket, parses the input, and raises an appropriate event.
Additional requirements:
The application should not rely on a UI thread (it may be run as a console application).
The main program should process messages synchronously, i.e. in the order in which they arrived.
The main thread must not block on waiting for timers (I guess this means I have to run timers on different threads).
And now for some questions :-):
I'm guessing requirement #1 means that I don't have a built-in message pump, so I can't use Invoke() from the socket listener / timer threads. Is this correct?
How can I safely raise events on one thread (e.g. the listener), and have the subscribers run synchronously on another (the main thread)?
It is very likely that new events will be raised before the subsequent handler is done. What will happen in this case? Will the event be buffed somewhere by the CLR, or will it be ignored?
And last but not least: I guess I'm aiming for the parallel for the message 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 automated trading engine which has to respond to events that happen in the market (e.g. a change in the price of a stock). When this happens, there may be multiple subscribers on the main thread which should be invoked, which is a classical scenario to use events.
I guess I can always use the Producer/Consumer with some message queue, and have the consumer raise events on the main thread, but I figured there might be a more direct way.

I think using messages will be the simplest way. If you are using C# 4 this is very easy thanks to the BlockingCollection<>
So have a shared BlockingCollection, where Message is your message class.
Then in your worker thread you do this
var msgEnum = blockingCollection.GetConsumingEnumerable();
//Per thread
foreach( Message message in msgEnum )
{
//Process messages here
}
That is it.
The GetConsumingEnumerable() will block until there is a message to process. It will then 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 in each one you just have the foreach loop.
When you are done call blockingCollection.CompletedAdding();
BTW the queue handles concurrency and will queue messages sent at the same time etc.
Hope this helps
Andre

You could implement a shared queue between your threads. Whenever an event is raised you could push it in the queue. The main thread is an endless loop that checks for new events, removes them from the queue, handles the event and when there are no more events it sleeps for some time.

Related

In a Console.ReadLine() statement when an event is received in C#

I'm currently writing a program which involves sending and receiving messages via a Serial connection. For that purpose, I'm using events to handle the reception of messages(I've tried doing it without them, but I didn't find anything but problems, and I'm not sure if it is due to the sending messages part of the code or the reception of messages part) and a question arose. If I'm in a Console.ReadLine statement, in which I haven't written anything yet, and an event is received, would the event be received and handled or not? More precisely, what would happen in that situation?
read the documentation of the serial connection about what thread the events are raised on.
The DataReceived event is raised on a secondary thread when data is received from the SerialPort object. Because this event is raised on a secondary thread, and not the main thread, attempting to modify some elements in the main thread, such as UI elements, could raise a threading exception. If it is necessary to modify elements in the main Form or Control, post change requests back using Invoke, which will do the work on the proper thread.
Since it is received on a background thread it will run independently from your other threads, possibly concurrently with your readLine. So you will need to ensure that the code is threadsafe.

Event handler timing and threading

I am still learning C# so please be easy on me. I am thinking about my application I am working on and I can't seem to figure out the best approach. This is not a forms application but rather a console. I am listening to a UDP port. I get UDP messages as fast as 10 times per second. I then look for a trigger in the UDP message. I am using an event handler that is raised each time i get a new UDP packet which will then call methods to parse the packet and look for my trigger. So, i have these questions.
With regard to threading, I assume a thread like my thread that listens to the UDP data should be a permanent thread?
Also on threading, when I get my trigger and decide to do something, in this case send a message out, i gather that I should use a thread pool each time I want to perform this task?
On thread pools, I am reading that they are not very high priority, is that true? If the message I need to send out is critical, can i rely on thread pools?
With the event handler which is raised when i get a UDP packet and then calls methods, what is the best way to ensure my methods all complete before the next packet/event is raised? At times I see event queue problems because if any of the methods take a bit longer than they should (for exampe writing to a DB) and the next packet comes in 100ms later, you get event queue growth because you cannot consume events in a timely manner. Is there a good way to address this?
With regard to threading, I assume a thread like my thread that listens to the UDP data should be a permanent thread?
There are no permanent threads. However there should be a thread that is responsible for receiving. Once you start it, let it run until you no longer need to receive any messages.
Also on threading, when I get my trigger and decide to do something, in this case send a message out, i gather that I should use a thread pool each time I want to perform this task?
That depends on how often would you send out messages. If your situation is more like consumer/producer than a separate thread for sending is a good idea. But if you send out a message only rarely, you can use thread pool. I can't define how often rare means in this case, you should watch your app and decide.
On thread pools, I am reading that they are not very high priority, is that true? If the message I need to send out is critical, can i rely on thread pools?
You can, it's more like your message will be delayed because of slow message processing or slow network rather than the thread pool.
With the event handler which is raised when i get a UDP packet and then calls methods, what is the best way to ensure my methods all complete before the next packet/event is raised? At times I see event queue problems because if any of the methods take a bit longer than they should (for exampe writing to a DB) and the next packet comes in 100ms later, you get event queue growth because you cannot consume events in a timely manner. Is there a good way to address this?
Queue is a perfect solution. You can have more queues if some messages are independent of others and their execution won't collide and then execute them in parallel.
I'll adress your points:
your listeting thread must be a 'permanent' thread that gets messages and distribute them.
(2+3) - Look at the TPL libarary you should use it instead of working with threads and thread pools (unless you need some fine control over the operations which, from your question, seems like you dont need) - as MSDN states:
The Task Parallel Library (TPL) is based on the concept of a task, which represents an asynchronous operation. In some ways, a task resembles a thread or ThreadPool work item, but at a higher level of abstraction
Look into using MessageQueues since what you need is a place to receive messages, store them for some time (in memory in your case)and handle them at your own pace.
You could implement this yourself but you'll find it gets complicated quickly,
I recommend looking into NetMQ - it's easy to use, especially for what you describe, and it's in c#.

Waiting for event to fire on a main thread from a background thread spawned by it

I have a situation where I am processing some data in a thread that is fired from an event initially, but it needs to wait until something happens in the main thread before continuing - the issue being there could be any number of these running concurrently. The real basic example:
Event Triggered -> Method set to run in the background on its own thread -> send data using the main thread's send data method -> Wait for an ACK for receipt of that data -> Set the WaitHandle on the main thread -> worker thread will then send the next set of data -> repeat -> exit thread when all data has been sent and ACK'd.
Currently I have one AutoResetEvent that is set each time an ACK comes in - and the worker thread that is running will listen for that - but if there happens to be 10 of those worker threads running at once, and they are all listening to it - it defeats the purpose.
I need to spawn the worker thread, and have it listen (WaitOne) for a specific WaitHandle to be set/reset, and continue based on that only.
What would be the best method for accomplishing something like this? Somehow create an array of WaitHandles and have the worker thread listen for the AutoResetEvent of its index?
I'm not sure on the exact way that your threads and your other process are interacting but a pattern I've used before is a dictionary, where a manual or auto reset event is the value, and you set some kind of ID as the key e.g the event, event sender, user ID whatever.
That way you can search for the relevant ID in the dictionary (using the default indexer) and then wait on the handle. If you need to add wait handles to the list asynchronously (e.g. as the events are raised) you may need to use a ConcurrentDictionary class. I'm not exactly sure what you need, but you could also look at a queue if you need to wait on all events being complete before completing some action.
Watch out for cross thread synchronisation. You don't want to block your main thread on a GUI app, and you can't edit a GUI from the same thread
I think you're digging a little too low-level in your abstractions. Is there a reason you can't use a much more typical producer-consumer model with a queue or two to handle in-flight requests and responses? It's going to be a lot easier to get it correct when you're not trying to recreate low-level synchronization primitives.

Wait for COM Event to complete

How do I block the UI thread while waiting for COM event to complete. I subscribe to update event of COM which signals the event has completed.
MyRData.OnUpdate += OnUpdate;
I do not own the COM code and cannot make changes to it.
I tried AutoResetEvent however that blocks the UI thread and i dont recieve updates from COM.
My answer is very similar to #EricBrown's one, but there is one different point.
Creating a nested message loop with MsgWaitForMultipleObjectsEx may lead to code reentrancy on the same thread (via a window message dispatched by the inner PeekMessage/TranslateMessage/DispatchMessage pattern). At worst scenario, you may end up calling the same COM object method before the previous call has returned.
I would first try using CoWaitForMultipleHandles with COWAIT_DISPATCH_CALLS (but without COWAIT_DISPATCH_WINDOW_MESSAGES). In case your COM object is provided by an out-of-proc server, this most likely should work. Otherwise, you should consider putting some reentrancy checks in place.
I have a related question with some code showing how it could be done with C# (I had to use COWAIT_DISPATCH_WINDOW_MESSAGES there, otherwise the event I was after wasn't getting fired).
[UPDATE] Ideally, you should use async/await pattern for things like that and wrap your event as a task (e.g. here's how). I understand, sometimes it is not feasible to re-factor existing code to use this approach. However, if a pending operation takes considerable time to complete, a more user-friendly way to wait for its completion event might be just to show a modal dialog with a nice "please wait..." message (as discussed here in comments). You'd just close this dialog from your event handler. In fact, AFAIK, this is the only endorsed way for a WinForms app to enter a nested message loop.
[UPDATE] As Eric pointed out in comments, COWAIT_DISPATCH_WINDOW_MESSAGES is indeeded required for an STA thread. Apparently, COWAIT_DISPATCH_CALLS is intended for the new little-known ASTA model and has no meaning in other apartment types.
In case with out-of-proc COM servers, .NET event handlers are called back as free-threaded objects regardless of the waiting thread's apartment model (in my experience, it's never the same STA thread on which the out-of-proc object was originally created). Thus, waiting with WaitHandle.WaitOne (no pumping) should be sufficient. However, if the event handler accesses any state data besides the WaitHandle, proper synchronization is required (with locks etc).
Most likely you want to pump messages while waiting for an event. For this, MsgWaitForMultipleObjectsEx is invaluable. I have an answer (to a different question) that demonstrates a common usage pattern for MsgWaitForMultipleObjectsEx.
I finally ended up using
Application.DoEvents()

What happens when an event occurs while program is working

I have a question regarding events in c#. What happens when program is working (for example a loop is executed and it takes a couple of minutes to finish) and an event occurs ( for example FileSystemWatcher will call "created" event ).
Event will be ignored?
FSW will not call the event, so creating new file will be ignored?
The code which has to be executed when event occurs will be executed after the loop ends?
Of course loop has nothing to do with this event, and no background workers or so are used.
This depends a lot on the implementation. In the case of FileSystemWatcher I would expect that event to be raised on a worker thread created by the system - so it will happen concurrently with the loop. If it was a UI event, I would expect it to be appended to the message loop's queue, to be processed after any work currently blocking the UI thread (which you shouldn't do). It would be unusual for an event to just disappear into nowhere unless that was a deliberate design feature - which seems unlikely.
In the case of many other events that are caused by regular code - they are usually processed synchronously when encountered.
So we have 3 options:
processed synchronously by the causing thread
invoked on a worker thread
added to the UI thread's queue (typically via "sync-context")
In this case, I believe the answer is "invoked on a worker thread", but all 3 are possible for events more generally

Categories