Files
2026-04-17 14:55:32 -04:00

6.7 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
Common/DTS.CommonCore/BusyIndicatorManager/xBusyIndicator.xaml.cs
Common/DTS.CommonCore/BusyIndicatorManager/BusyIndicatorManager.cs
2026-04-16T02:11:43.845066+00:00 Qwen/Qwen3-Coder-Next-FP8 1 85046dce961f12c2

BusyIndicatorManager

Documentation: BusyIndicatorManager Module


1. Purpose

This module provides a centralized, singleton-based busy indicator management system for WPF applications, enabling multiple components or operations to request and release busy state independently while ensuring the UI reflects a consistent busy status. It decouples the initiation of busy operations (via unique IDs) from the actual display of the busy indicator, which is expected to be bound to the IsBusy and Message properties of the BusyIndicatorManager instance. The xBusyIndicator class serves as the XAML-backed UI control that presumably consumes this manager (though its current implementation is minimal).


2. Public Interface

BusyIndicatorManager (Singleton)

  • public static BusyIndicatorManager Instance { get; }
    Thread-safe singleton accessor. Returns the single shared instance of BusyIndicatorManager. Uses double-checked locking via SyncRoot.

  • public bool IsBusy { get; }
    Read-only property indicating whether any busy request is currently active. Raises PropertyChanged on change (via NotificationObject base).

  • public string Message { get; }
    Read-only property containing the current busy message. Reflects the message of the last added or active busy request (see ShowBusy/CloseBusy behavior). Raises PropertyChanged on change.

  • public void ShowBusy(int id, string busyMessage)
    Registers a new busy request with the given id. If id is new, it adds the busyMessage to the internal dictionary and sets IsBusy = true and Message = busyMessage. If id already exists, it updates the stored message for that id, and ensures IsBusy = true and Message = busyMessage (i.e., overwrites current message regardless of prior state).
    Note: Does not deduplicate or prevent multiple ShowBusy calls with the same id—only updates the message.

  • public void CloseBusy(int id)
    Removes the busy request identified by id. If no requests remain (busyParameters.Count == 0), sets IsBusy = false and Message = "". Otherwise, sets IsBusy = true and Message = busyParameters.Last().Value (i.e., the message of the last-enumerated remaining request).
    Note: Enumeration order of Dictionary<int, string> is insertion order in .NET, but relying on Last() for priority is fragile and not guaranteed to be intuitive.

xBusyIndicator (UI Control)

  • public xBusyIndicator()
    Constructor. Calls InitializeComponent() to load the XAML-defined UI.

  • public void Connect(int connectionId, object target)
    Currently empty implementation. Presumably intended to associate a UI element (target) with a logical connection ID (connectionId), but no behavior is defined in the source.


3. Invariants

  • Singleton uniqueness: Exactly one instance of BusyIndicatorManager exists per AppDomain (enforced via lock and null-check).
  • IsBusy truthfulness:
    • IsBusy == true iff busyParameters.Count > 0.
    • IsBusy == false iff busyParameters.Count == 0.
  • Message consistency:
    • When IsBusy == true, Message equals the busyMessage string associated with the last-enumerated entry in busyParameters.
    • When IsBusy == false, Message == string.Empty.
  • ID uniqueness per request: Each id in ShowBusy(id, ...) maps to one message in busyParameters. Reusing an id updates the message but does not create a new entry.

4. Dependencies

Dependencies of this module:

  • Microsoft.Practices.Prism.ViewModel.NotificationObject: Base class for BusyIndicatorManager, enabling property change notifications (RaisePropertyChanged).
  • System.Collections.Generic: Used for Dictionary<int, string>.
  • System.Linq: Used for busyParameters.Last() in CloseBusy.
  • WPF UI framework: xBusyIndicator inherits from System.Windows.Controls.UserControl (implied by InitializeComponent() and XAML usage).

Dependencies on this module:

  • UI components (not visible in source): Presumably XAML views bind to BusyIndicatorManager.Instance.IsBusy and .Message to drive a BusyIndicator control (e.g., from Xceed.Wpf.Toolkit).
  • xBusyIndicator.xaml: The XAML file for xBusyIndicator (not provided), which likely consumes BusyIndicatorManager to display the busy state.

5. Gotchas

  • CloseBusy message selection is arbitrary: busyParameters.Last() uses dictionary enumeration order, which is insertion order in .NET, but this is not documented as a contract. If multiple requests are active, the displayed message may change unexpectedly when an unrelated request is closed.
    Example: Requests added in order id=1, id=2, id=3 → closing id=2 changes message to that of id=3, even if id=1 was the "primary" request.

  • No validation on id: ShowBusy and CloseBusy accept any int. Duplicates are allowed (with update semantics), but no error is thrown for invalid IDs.

  • Connect method is a stub: xBusyIndicator.Connect has no implementation. Its purpose is unclear—without knowing the intended use of connectionId and target, this API is non-functional.

  • No thread-safety for busyParameters: While singleton instantiation is thread-safe, all operations on busyParameters (e.g., ContainsKey, Add, Remove, Last) are not synchronized. Concurrent calls to ShowBusy/CloseBusy from multiple threads may cause race conditions (e.g., KeyNotFoundException, corrupted dictionary state).
    Note: The singleton uses a lock for initialization only.

  • Message overwriting on id reuse: Calling ShowBusy(42, "A") then ShowBusy(42, "B") updates the message but does not reset IsBusy if it was already true. This may be intentional, but could mask bugs if callers assume each ShowBusy is independent.

  • Hardcoded property names: RaisePropertyChanged("IsBusy") uses string literals. No compile-time safety—renaming properties would break binding silently.

  • No timeout or cancellation support: Busy state persists indefinitely until CloseBusy(id) is called. No mechanism to auto-release or cancel long-running requests.

  • Xceed.Wpf.Toolkit imported but unused: The namespace is imported in xBusyIndicator.xaml.cs, but no Xceed.Wpf.Toolkit types are referenced in the provided code. May indicate future use or leftover artifact.