I have a class called SerialClient that sends/receives bytes over a serial port. When SerialClient.Start() is called it goes into an infinite while loop, until SerialClient.Stop() is called. The class has some properties, for simplicity lets say SerialClient.PropA, SerialClient.PropB.
I need to use this in a GUI. Where by on the GUI you can call Start, Stop and read the properties as they change.
In order to use this in a GUI, obviously SerialClient needs to operate in a thread as its an endless loop. So, I have setup the view with properties to match that of SerialClient. The view calls Start() and Stop() on the presenter.
In the presenter I create a new thread and call start on an object of SerialClient. The problem is when _serialClient throws an exception the presenter cannot catch it, and also if the properties like (SerialClient.PropB) change and call their changed event handlers, they need to be invoked on the GUI thread. I tried using the background worker, but couldn’t get it working (changing properties still hit the UI from the non-UI thread).
Thread thread = new Thread(_serialClient.Start);
thread.IsBackground = true;
thread.Start();
There must a simple solution I am over looking. The GUI just needs to call methods and read properties, and prevent exceptions crashing the whole application.
Any ideas?
You hit 2 of the common problems usually seen when dealing with multithreaded application in C#:
Dealing with exception in the background thread. When exceptions occurs in the background thread, they travel up the stack, from caller to caller to see if anyone is able to catch that exception. If the original call occurs from outside your own calls (for example, a callback from a serial port or a timer) you may or may not be notified of the exception. As a typical solution to this, what I have seen is to wrap in a try-catch the code that can throw the exception and to have an event handler push the exception to a thread that will be able to handle the exception appropriately (log, notify the user, terminate, all of the above)
Events are always excuted on the thread that calls them. You have to manually marshall the call to the UI thread using Dispatcher and Invoke. The most succint code to do it I found is here