4

I am building an application where it is possible to monitor some MCU hardware (sensors readings etc) in real time. For the communication I am using a CAN bus.

Basically i have 2 threads as of now. One is the main thread where the GUI is running and the other is managing/monitoring the communication between the device. So the obvious thing is that i need to pass the data from the communications thread to the gui thread. However what should be the right way to do it? I know how to pass a data back to the calling thread when the child thread has finished working, but in this case the communications thread is running all the time.

Of course the communications logic is represented by a separate class (CANManager).

I have couple of ideas of my own, however I would like to know what is the "right" way how this should be done.

Thanks in advance :)

xnonamex
  • 405
  • 2
  • 5
  • 17
  • *However what should be the right way to do it?* Possible duplicate of https://www.google.com.au/search?q=wpf+invoke+on+main+thread – ta.speot.is Nov 22 '13 at 09:53
  • Take a look at the BackgroundWorker class, where you could utilize the 'ProgressChanged' event: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.progresschanged(v=vs.110).aspx | As you are using .NET 4.5 you could also use the Task class, which lets you continue with the same process, as soon as your child process has finished: http://msdn.microsoft.com/en-us/library/dd270696(v=vs.110).aspx – Kai Hartmann Nov 22 '13 at 09:57
  • My initial idea was just to create a "storage class" which would hold all the necessary values as properties. so i could update those properties asynchroniously from my communication thread and then just bind those properties to the wpf. :) – xnonamex Nov 22 '13 at 10:34
  • 1
    do you mean a 'ViewModel' ? :) – Dr. Andrew Burnett-Thompson Nov 22 '13 at 11:03
  • could be. as you might have guessed im not a specialist in oop and c#, since my primary thing is embedded c. But can that be a thing? it just seems the most simple thing if it works? – xnonamex Nov 22 '13 at 12:49

1 Answers1

5

Generally in any programming language you need to consider a pub-sub architecture for communicating across threads. This means that for each thread A which wishes to send a message to thread B, you should post a 'message' or event from that thread onto a queue, to be consumed by another thread when it is free. If you just google 'Cross Thread communication c#' you will find numerous articles to read over.

Specifically, in .NET the way to invoke a method or delegate on another (any) thread is to use SynchronizationContext. This is common to both Windows Forms and WPF, whereas WPF has a Dispatcher which is distinct to this framework to invoke on the UI thread only.

There are many frameworks, libraries, patterns available to do this sort of technique. One of them is the Task Parallel Library. TPL allows you to create a Task, or Task and invoke it on a threadpool, UI, same or specific thread. TPL allows thread marshalling via the use of Schedulers. You can use the built-in Schedulers or create your own. Schedulers use SynchronizationContext at their heart to do the thread marshalling.

One particularly interesting pattern of TPL is the ability to run a delegate on one thread and then chain multiple operations on other threads, e.g. on completion or on error. I would look into the Task Asynchronous Pattern and consider returning Task from async methods so you can chain on them using ContinueWith.

Dr. Andrew Burnett-Thompson
  • 20,980
  • 8
  • 88
  • 178