using System; using System.Collections.Generic; using System.Threading.Tasks; namespace PCL.Core.Utils.Threading; // 使用 AI 生成的代码 // 时间: 2025/9/2 // 模型: GPT-5 /// /// 一个带配额(Permit)的 变体。 /// 支持一次性释放多个等待任务。 /// 类似于 ,但语义更接近 AutoResetEvent。 /// public sealed class AsyncCountResetEvent : IDisposable { private readonly Queue> _waiters = new(); private readonly object _lock = new(); /// /// 当前剩余的配额数。如果 > 0,新的等待者会立即通过。 /// private int _permits; /// /// 标记当前对象是否已释放。 /// private bool _disposed; /// /// 析构函数。 /// ~AsyncCountResetEvent() { Dispose(); } /// /// 等待一个信号。当信号可用时返回完成的 。 /// 如果没有信号,则进入队列等待。 /// /// /// 一个 ,表示等待操作。 /// 如果对象被释放,则返回的 Task 会异常结束。 /// public Task WaitAsync() { lock (_lock) { ObjectDisposedException.ThrowIf(_disposed, nameof(AsyncCountResetEvent)); if (_permits > 0) { _permits--; return Task.CompletedTask; } var tcs = new TaskCompletionSource( TaskCreationOptions.RunContinuationsAsynchronously); _waiters.Enqueue(tcs); return tcs.Task; } } /// /// 释放一个或多个信号,让等待者继续执行。 /// /// 要释放的配额数量,默认为 1。 public void Set(int count = 1) { if (count <= 0) return; lock (_lock) { if (_disposed) return; while (count > 0 && _waiters.Count > 0) { var tcs = _waiters.Dequeue(); tcs.TrySetResult(true); count--; } // 如果没有等待者,就累积到配额里 _permits += count; } } /// /// 释放当前对象。 /// 会让所有等待中的任务异常完成。 /// public void Dispose() { lock (_lock) { if (_disposed) return; _disposed = true; while (_waiters.Count > 0) { var tcs = _waiters.Dequeue(); tcs.TrySetException(new ObjectDisposedException(nameof(AsyncCountResetEvent))); } } GC.SuppressFinalize(this); } }