1

I have an industrial equipment which is controlled by a software. The software connects to it using sockets, and keeps the connection all the time alive, while from time to time sending commands to the equipment. Now, this equipment is represented by a class which encapsulates the sending and receiving of data.

Next, I need to make a UI, that will show the state of the equipment, independent from the controlling software (controlling is on a different thread same solution). Refresh to the UI must be done lets say every second, but it can happen that UI wants to read data, and the controlling software wants to write.

The problem is that the equipment might respond from 50 ms to 1 second, we don't know, and during the response no one must interfere!

How can I best synchronize calls to the equipment communication class?

There might be at least 2 solutions:

  1. Using simple lock(obj) {} statement in C#, for each method in the common. class
  2. Using events and a message queue with a subscriber concept

While the first one might be simple, I assume for my case is the worst solution because it can block everything.

The second one seems more OK, but the problem is that there will be for sure some delay on receiving the results if many subscribers are, or dunno, I'm not really sure.

UPDATE: I implemented using simple lock. The reason is that some equipment do not have (some do, but most not), on their controller side, the possibility to process multiple request, and their buffer will overflow. So to make sure nothing bad happens, exclusive READ/WRITE lock is best solution I have found so far, and it works.

  • If many subscribers are what? – Esben Skov Pedersen Aug 26 '14 at 8:40
  • Delay in receiving the actual result. The result need to be as close to the requested time as possible. Only thing I think is just to put a DateTime in there with the time when the result was received, and only after that to send to subscribers – XMight Aug 26 '14 at 8:55
  • Also if a thread is requesting too many times a value, others will be spammed with the result, even if they don't need it. In my case there are different values that are requested from the equipment, and different threads can be interested in different results. – XMight Aug 26 '14 at 9:44
  • I dont think you need to concern yourself too much about different threads will receive values they dont need. When you are dealing with sockets they will be much much slower than anything in memory. I also favor solution 2 because locks dont have any defined order in which they will be opened. – Esben Skov Pedersen Aug 27 '14 at 9:01
2

Either solution would work. It is a generally good idea to apply a lock when writing to such values. If you're expecting a lot of reads, then you could use ReaderWriterLockSlim to put a write lock on it, which would prevent other threads from writing the value, but it could be read with no locking whatsoever. This assumes that the value, at any point in time in your critical area, accurately shows the state of the equipment (in other words, don't set it to zero temporarily, since another thread could read it in that moment).

I would personally favor the 2nd solution since it decouples the value being changed from thread/threads that wish to use it for some scope. I use the ReaderWriterLockSlim in combination, however, you need not put the value change event publishing inside the critical area since you can't make any assumptions about how the event will be handled by the subscribers, even if in this case it is simply to update the UI. Should your program change in the future, it would be easy to later adapt it to accomodate new uses for changes made to the value.

Hope that helps!

  • Actually I assume that I cannot use ReaderWriterLockSlim, because even if I read something from the industrial equipment, for the equipment it acts as a write, and it must be exclusive, no other request must interfere, otherwise data will be corrupt, that's the problem. Basically one read or write at a time. Does this change something in your answer? – XMight Aug 26 '14 at 8:59
  • @XMight Is there a chance that the read would fail? If so, then you should perhaps read to a local variable, and if it succeeds, only then assign the value that will ultimately be read by other threads. However, there shouldn't be any impact on using ReaderWriterLockSlim since that is for the benefit of intereference from other threads, not from the equipment. – Neil Aug 26 '14 at 9:13
  • Yes, there is a chance that it will fail, the equipment might not answer in due time. Now, if I put lock, why use ReaderWriterLockSlim in my case over simple lock(obj)? – XMight Aug 26 '14 at 9:20
  • @XMight The advantage over a simple lock is that your UI thread can read the value at any time (which is also why you shouldn't assign it until successful read to local variable). It will still prevent the value from being written by other threads. It may not even be particularly useful to use a lock if you don't ever write it in another thread. – Neil Aug 26 '14 at 9:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.