using System; using System.Collections.Generic; using System.Linq; namespace WhiteMagic.Thread; /// /// A disposable scope that tracks a set of threads frozen by . /// Disposing the scope resumes exactly those threads, in reverse order, even if the guarded /// body throws, and then disposes the underlying thread handles. /// public sealed class FrozenThread : IDisposable { private readonly IReadOnlyList _threads; private bool _disposed; internal FrozenThread(IReadOnlyList threads) { _threads = threads ?? throw new ArgumentNullException(nameof(threads)); } /// The threads suspended by this freeze scope. public IEnumerable Threads => _threads; /// /// Resumes the frozen threads in reverse order, then disposes every thread handle. /// public void Dispose() { if (_disposed) return; _disposed = true; foreach (RemoteThread thread in _threads.Reverse()) { try { thread.Resume(); } catch { // Resume-on-dispose is best-effort; the handle is still disposed below. } } foreach (RemoteThread thread in _threads) { thread.Dispose(); } } }