From this code, it is not clear what delay in serial communication is required and why, but the implementation of the delay is wrong anyway. You use spin wait which should be avoided by any means. Spin wait use 100% of the CPU core without any purposes.
All wait methods should be based on thread methods. 1) To wait unconditionally for certain amount of time, use
System.Threading.Thread.Sleep
. 2) If you need to wait until certain condition,
always use
System.Threading.EventWaitHandle.WaitOne
(with timeout or not). In both cases, the thread is switched off by OS and never scheduled back to execution until waken up by OS. It will be waken up by expiration of time, or the following methods called from another thread:
Thread.Abort
or
System.Threading.EventWaitHandle.Set
(second one to be used if a thread is in the wait state at the call to
System.Threading.EventWaitHandle.WaitOne
on the same instance of
EventWaitHandle
.
Do I even have to mention that your serial communication should be done in a separate thread, not UI thread? This is absolutely important.
Now, it looks like by some reason you need to wait until the UI is fully updated with new data. First, think again, do you really need it? If you insist on that (yes, it can be a good solution by several reasongs), it can be achieved a bit simpler. You can use
Dispatcher.Invoke
instead of
Dispatcher.BeginInvoke
. First method delays the thread calling
Invoke
be the end of the actual call of the delegate, while
BeginInvoke
will return as soon as delegate instance and the data used for the call are placed to the invocation queue of the UI thread.
For more detail on invocation, see also my past Answers:
Control.Invoke() vs. Control.BeginInvoke()[
^]
Problem with Treeview Scanner And MD5[
^]
[EDIT]
You need certainly to put port communications in a separate thread, good point.
The main design idea is: as you do the communications during all the life time of your application, it can be created from the very beginning and kept running. It can be synchronized using thread synchronization primitives.
Best way to create such a thread is to use my thread wrapper:
How to pass ref parameter to the thread[
^].
Other options include using a thread pool (you can create a similar wrapper) or
BackgroundWorker
(which I would rather recommend for temporary tasks.
A good way to organize synchronized communication is using a generic blocking queue. See my Tips/Tricks article and the "alternative" answer (not really alternative, it's just the advice to use the similar class available in v.4.0):
Simple Blocking Queue for Thread Communication and Inter-thread Invocation[
^].
At to WPF, it is important to know that you cannot call any UI elements from non-UI thread, so you need to use inter-thread invocation. For WPF, you should use
Dispatcher.Invoke
or
Dispatcher.BeginInvoke
. See my other Answers for the explanation of how it works and the samples:
Control.Invoke() vs. Control.BeginInvoke()[
^]
Problem with Treeview Scanner And MD5[
^].
—SA