C# Events firing on wrong thread - c#

All
I have an application that allows a user to communicate with multiple serial devices.
A manager class is used to start the application, which creates a new thread for each serial device. Inside this thread, the serial device is created and the thread and serial device object are stored inside the manager class for later when needed.
The serial device class then creates a com port class on it's own new thread which is used to connect to the com port and send / receive data. When data is received an event is fired up to the serial device class which in turn fires an event to the manager class, which in turn fires an event to the UI to alert the user that new data has arrived.
My problem comes that when the com port class fires it's event to notify the serial port class, the serial port class receives the event and continues processing under the com port thread. Likewise if the user sends any information down to the com port, it all runs under the UI thread.
I will add code as an edit later, but for now, if anyone can spot anything obvious I would be seriously greatful.
I have tried receiving the event in the serial device class and then invoking a method to see if that makes it run under the correct thread but that was no good.
I know the serial device thread is running as I do an Application.Run inside the class after it's created it's com port classes.
I'm not using any background workers as these threads are meant to exist for the life of the application and I understand background workers are meant to be used for short running calculations.
Many thanks
EDIT:
Forgot to mention, this is a Winforms app in .NET 2.0, so no Dispatcher available
EDIT:
Okay, so it looks like that the information is being passed up inside the DataReceived thread (I think as it isn't the com port thread either).
I also tried using a BackgroundWorker for the serial device class but this also didn't make any difference.
Help?

.NET 2.0 has SynchronizationContext. It's a slight pain (you have to pass the context from the UI thread to the others) but it should do the trick.
More info here: http://msdn.microsoft.com/en-us/magazine/gg598924.aspx

It sounds as if you need to create a kind of messaging mechanism to send messages from the UI thread to the correct port-thread. A queue might work. Let the UI thread post messages on the queue and have the port-thread process these messages.
Switching from the port-thread to the UI thread can be done using Dispatcher.CurrentDispatcher
Is this what you are looking for?
EDIT I am assuming a WinForms application

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.

Synchronization between GUI Updating thread & processing thread

I have developed one application in which i am continuously sending request and reading response at serial port and updating huge GUI comprise of zed graphs, objectlistviews, analog meters.
Currently i am using one thread which is performing request & response at serial port and pushing the data into queue , and another thread which is fetching data from queue and updating the GUI.
for this i am making the use of Autoresetevent(Set and waitone) for notifying the GUI thread when data is available in the Queue.
This is actually sequential operation so whatever data comes at serial port should be immediately updated into GUI. Something like below model
1 Response -> Update GUI -> 2 Response -> update GUI -> 3 Response -> update GUI -> so on ..
Whenever i get any error at the serial port complete model get mess up and GUI is not updated properly.
Can anybody please let me know what approach should be implemented for achieving the above?
As English is not my first language, let me know if anybody needs further improvements in the question.
.net framework 3.5 SP1 and VS 2008
sent methods can be called from gui thread, it is OK. Problem is on receiving. You can simply set checkforillegalcrossthreadcalls to false and directly call main (gui) thread method within serial port's datareceived method. However I would not use this method.
I would prefer calling a delegate method to update GUI.

Events not working in Windows Service

I've created a managing application. On of the things my application does, is register on a plugin which can detect whenever or not a fingerprint reader gets plugged in or plugged out. The class subscribes on the event like such:
//Subscribe to the plug, unplug and imageAcquired events from the GrFingerXCtrlClass library.
FingerXCtrlClass.SensorPlug += ReaderPlug;
FingerXCtrlClass.SensorUnplug += ReaderUnplug;
FingerXCtrlClass.ImageAcquired += ImageAcquired;
First when I was actively working on the program, I've developed a WPF application. Through this application I could see some of the lists and switch some settings so I am sure my service works well. In this WPF application, I've created my service by instantiating it:
ProjectServiceLogic logic = new ProjectServiceLogic();
Now I've created an installer. Thus I had a ProjectService-class, initializing the application. This is being done like so:
protected override void OnStart(string[] args)
{
log.Debug("Starting service...");
_worker = new Thread(new ThreadStart(StartService));
_worker.IsBackground = true;
_worker.Name = "ServiceThread";
_worker.SetApartmentState(ApartmentState.STA);
_worker.Start();
log.Debug("Successfully started service");
}
void StartService()
{
serviceLogic = new ProjectServiceLogic();
while (!_shutdownEvent.WaitOne(0))
{
}
}
The program gets installed and the service starts. When debugging the service, I notice the subscribing code gets executed. However, the events are not triggered when I plug in a device while it does trigger when running it locally through the WPF application, instantiating the service logic. Why doesn't it work now?
_worker.SetApartmentState(ApartmentState.STA);
Selecting a Single Threaded Apartment requires you to implement the contract of an STA thread. Just two basic requirements: you can never block the thread and you must pump a message loop. The message loop is essential to allow COM to provide the guarantee that method calls on the COM object are always made from the thread that created the object, thus ensuring thread-safety. Also the mechanism in .NET that makes Control.BeginInvoke and Dispatcher.BeginInvoke work.
A COM component counts on having that guarantee in place, it often relies on the message dispatcher to take care of its own inter-thread marshaling. Like Dispatcher.BeginInvoke does.
Two things go wrong when you don't in fact pump a message loop as required. First of all, as expected, any calls you make on the object from a worker thread will deadlock. COM will use PostMessage to ask the STA thread to dispatch the call. But that won't happen when the thread isn't retrieving messages from the message queue. Second thing that goes wrong is likely what you see happening here, the component itself uses PostMessage to raise events on the STA thread. With the failure mode that the event is never raised. Also classically the way WebBrowser misbehaves, you never get the DocumentCompleted event.
You'll need to pump a message loop, Application.Run(). Either the Winforms or the WPF version of it will do, take your pick. A Winforms example is here

How to receive multiple tasks at the same time in a single com port in c sharp

Im a novice in c sharp and im stuck with this task. My requirement is , I create many threads and these threads (send using COM1) have to communicate with a single serial port say COM2. All the threads have to send message using a single COM port(receive using COM2).
say,send "helloworld1"(using thread1) and "helloworld2"(thread2) using COM1 and receive using COM2 in hyperterminal. So i need to see both the helloworlds in the hyperterminal at the same time.
Please help me out.
Since you want to send from two different threads, you will need to surround your calls SerialPort.Write() with a lock{} like this:
SerialPort s = new SerialPort();
//configure serial port, etc.
//spin off additional threads
//in each thread, do this:
lock(s)
{
s.Write("Hello World1");
}
You will want to start here.
You can instantiate 2 instances the SerialPort class for each COM port you want to send/receive on.
I have used 2 variations of receiving data us the SerialPort class:
1. You can manually "Read" on the port at a certain interval (e.g. you can have each thread read as needed).
2. The SerialPort class exposes a DataReceived event that can be subscribed to (an ErrorReceived is also available).
Option 1 might be the best fit.
Edit
After reading your comment, Option 2 may be a better fit so that you can have one "receive" thread that subscribes to the DataReceived/ErrorReceived events.
Per #Slider, the lock will also be required to ensure only 1 thread is writing at any given time.

issue/response serial port processing in C#

Okay here's the problem (this is related to a previous post of mine)
I need to be able to have an issue/response system for serial comms that works something like this:
issue: hello
response: world?
issues: no, hello nurse
reponse: well you're no fun.
this would mean I say "hello" the remote unit is expected to send back "world?" within some timeframe, and if it doesn't i should have a way to access that buffer, so here's what i'm thinking, please give me feedback
a ReaderWriterLock'd 'readBuffer'
a Issue Method that will write to the stream
a Response Method that will watch the readBuffer until it contains what i'm expecting or until the timeout expires.
first, how would the stackoverflow community design this class, second, how would they write the datarecieved event? Third how would they make this code more robust so that multiple instances of the class can exist in parallel threads for simultaneous communications?
This is basically a producer-consumer problem, so that should be the basis for the general design.
Here are some thoughts on that:
a) FIFO buffer (Queue)
First of all, you should have an instance of a thread-safe Queue (a FIFO buffer) for each instance of your class. One thread would receive the data and fill it, while the other one would read the data in a thread-safe manner. This only means you would have to use a lock on each enqueue/dequeue operation.
FIFO Queue would enable you to simultaneously process the data in the worker thread, while filling it from the communication thread. If you need to receive lots of data, you could dequeue some data in the worker thread and parse it before all of it has been received. Otherwise you would need to wait until all data has been received to parse it all at once. In most cases, you don't know how much data you are supposed to get, until you start to parse it.
b) Worker thread waiting for data
I would create a worker thread which would wait for a signal that new data has been received. You could use ManualResetEvent.WaitOne(timeOut) to have a timeout in case nothing happens for a while. When the data is received, you would have to parse it, based on your current state -- so that would be an implementation of a state machine.
c) Port abstraction
To handle different types of ports, you could wrap your serial port inside an interface, which could have at least these methods (I might have forgotten something):
interface IPort
{
void Open();
void Close();
event EventHandler<DataEventArgs> DataReceived;
void Write(Data data);
}
This would help you separate the specific communication code from the state machine.
NOTE:
(according to Microsoft) The DataReceived event is not guaranteed to be raised for every byte received. Use the BytesToRead property to determine how much data is left to be read in the buffer. So you could create your own implementation of IPort which would poll SerialPort in regular intervals to ensure that you don't miss a byte (there is a question of SO which already addresses this).
d) Receiving data
To receive the data, you would have to attach a handler for the IPort.DataReceived event (or SerialPort.DataReceived, if you're not wrapping it), and enqueue the received data to the Queue inside the handler. In that handler you would also set the mentionel ManualResetEvent to notify the worker thread that new data has been received.
I had a similar design issue writing an asynchronous socket listener for formatted data.
A translation of what I came up with into the SerialPort / DataReceived model would be something like this:
The main class encapsulates the issue/response system - it will contain the logic for generating the response based on input. Each instance of the class will be bound to a single serial port that can be set during or after construction. There will be a StartCommunications type method - it will wire up the DataReceived event to another method in the class. This method is responsible for grabbing the data from the port, and determining if a full message has arrived. If so, it raises its own event (defined on the class), which will have an appropriate method wired to it. You could also have it call a predefined method on your class instead of raising an event - I defined an event to improve flexibility.
That basic design is working just fine in a production system, and can handle more input than the rest of the systems connected to it can.

Categories