using System; using System.Threading; using System.Threading.Tasks; namespace PCL.Core.Utils.Threading; // Partly generated by gpt-5-mini (20250808) public sealed class AsyncManualResetEvent : IDisposable { private readonly object _syncLock = new(); private TaskCompletionSource _tcs = new(TaskCreationOptions.RunContinuationsAsynchronously); private readonly ManualResetEventSlim _mre = new(false); private bool _disposed; public AsyncManualResetEvent(bool initialState = false) { if (!initialState) return; _tcs.SetResult(true); _mre.Set(); } /// /// 事件是否已触发。 /// public bool IsSet { get { lock (_syncLock) { return _tcs.Task.IsCompleted; } } } /// /// 异步等待。 /// /// 用于结束等待的取消信号 public Task WaitAsync(CancellationToken cancellationToken = default) { TaskCompletionSource t; lock (_syncLock) { t = _tcs; } if (!cancellationToken.CanBeCanceled || t.Task.IsCompleted) return t.Task; return _WaitWithCancellationAsync(t.Task, cancellationToken); } private static async Task _WaitWithCancellationAsync(Task waitTask, CancellationToken ct) { var cancelTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); using (ct.Register(s => ((TaskCompletionSource)s!).TrySetResult(true), cancelTcs)) { var completed = await Task.WhenAny(waitTask, cancelTcs.Task).ConfigureAwait(false); if (completed == cancelTcs.Task) ct.ThrowIfCancellationRequested(); await waitTask.ConfigureAwait(false); // propagate exceptions if any } } /// /// 同步等待。 /// public void Wait() => _mre.Wait(); /// /// 同步等待,并在超时后结束。 /// /// 等待超时的毫秒数 /// 若已触发事件则为 true,否则为 false public bool Wait(int millisecondsTimeout) => _mre.Wait(millisecondsTimeout); /// /// 同步等待,并在超时后结束。 /// /// 等待超时 /// 若已触发事件则为 true,否则为 false public bool Wait(TimeSpan timeout) => _mre.Wait(timeout); /// /// 同步等待,并传递用于结束等待的取消信号。 /// /// 用于结束等待的取消信号 public void Wait(CancellationToken cancellationToken) => _mre.Wait(cancellationToken); /// /// 触发事件。 /// public void Set() { lock (_syncLock) { _tcs.TrySetResult(true); // Use TrySetResult to avoid exceptions on repeated Set _mre.Set(); } } /// /// 重置事件。 /// public void Reset() { lock (_syncLock) { if (!_tcs.Task.IsCompleted) return; // already reset _tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); _mre.Reset(); } } public void Dispose() { if (_disposed) return; _mre.Dispose(); _disposed = true; } }