Files
DP44/enriched-qwen3-coder-next/Common/DTS.CommonCore/BusyIndicatorManager.md

99 lines
6.7 KiB
Markdown
Raw Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- Common/DTS.CommonCore/BusyIndicatorManager/xBusyIndicator.xaml.cs
- Common/DTS.CommonCore/BusyIndicatorManager/BusyIndicatorManager.cs
generated_at: "2026-04-16T02:11:43.845066+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "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.