Skip to content

Thread-Safe Observed

The TSObserved<T> class is a thread-safe version of an observable value within the ByteCobra.Observables.ThreadSafe namespace. It's designed to allow multiple threads to safely access and observe changes to a value of type T.

TSObserved<T> ensures thread-safety by utilizing a lock mechanism when accessing or modifying the value and the list of subscribers. A lockObject is used in conjunction with the Monitor class to synchronize access to the value and the subscribers list. This is to ensure that only one thread can access these critical sections at a time, preventing race conditions.

The LockTimeout property allows specifying a timeout period for acquiring a lock. If a lock cannot be acquired within this period, an error is logged.

Subscribe, Unsubscribe, ClearSubscriptions, SetValueSilently, and NotifyChanged methods are implemented to ensure thread-safety by using the Monitor.TryEnter and Monitor.Exit methods to acquire and release a lock around critical sections of code. This prevents concurrent access from multiple threads which could lead to race conditions or other threading issues.

This class is a foundation for creating thread-safe reactive programming patterns, ensuring that observers are notified of changes in a thread-safe manner.


  • bool HandleExceptions: Controls if exceptions during change notifications should be handled internally or thrown externally.
  • TimeSpan LockTimeout: Specifies the timeout period for acquiring a lock on the value.


  • void Subscribe(Action<T> callback): Registers a callback to be invoked when the value changes.
  • void Unsubscribe(Action<T> callback): Unregisters a previously registered callback.
  • void ClearSubscriptions(): Clears all registered callbacks.
  • void SetValueSilently(T value): Sets the value without triggering change notifications.
  • void Subscribe(Action callback): Registers a callback to be invoked when the value changes, without providing the new value.
  • void Unsubscribe(Action callback): Unregisters a previously registered callback, which was registered without providing the new value.
  • void NotifyChanged(): Manually triggers a notification of the value change.


var tsObservedValue = new TSObserved<int>(10);

tsObservedValue.Subscribe((newValue) =>
    Console.WriteLine($"Value changed to {newValue}");

tsObservedValue.Value = 20; // Output: Value changed to 20