One problem that can happen with this approach that if a StartBackgroundWork
call is made very close in time to when the background task was just cleaning up, then:
_busy = false;
-happens-before- if(_busy)
may not be preserved. So you may miss some triggers.
As long as StartBackgroundWork
...is only ever called from one thread... you will not have overlapping executions, but the moment this condition is violated, the safety goes. Do note that this code might be maintained in future, and someone may call that method without considering (or understanding) threading implications. This type of guarantee is especially difficult to make for web applications.
One solution as proposed by @GhostTW is to perform the operations on _busy
under lock
. Locking does have some performance impact but is clean to maintain.
A smartass way to achieve the same objective would be to declare the flag as volatile
. This is super fast but the way it achieves is so, umm... twisted, that a slight misuse can cause more harm than good. If performance is not microsecond critical, then recommend going with lock.
Ideally a private method need not be threadsafe itself, but your business rules say something on what is allowed in parallel and what is not. That makes your method thread-aware. Making it thread-safe or not is your choice. Depending on how hard your business rule is, you might not have a choice. Questions to ask: (1) what if we do miss a trigger? Does a patient die? (2) What if the task does end up running twice in parallel? Does a patient die? (3) What if someone looks at my code? Will that question my consulting fees? (last one was a joke)