初始化 monorepo: Go后端(7微服务) + Unity客户端(9模块) + 启动器 HTML5原型: Three.js 3D体素世界, Perlin噪声地形, 原版材质, 22种方块 Minecraft创造模式背包: 双栏布局, 拖拽移动物品, 方向性元件引脚 AI助搭策划文档 + 客户端/服务端骨架 + Docker Compose + CI
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
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<bool> _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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 事件是否已触发。
|
||||
/// </summary>
|
||||
public bool IsSet
|
||||
{
|
||||
get { lock (_syncLock) { return _tcs.Task.IsCompleted; } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步等待。
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">用于结束等待的取消信号</param>
|
||||
public Task WaitAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
TaskCompletionSource<bool> 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<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
using (ct.Register(s => ((TaskCompletionSource<bool>)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
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同步等待。
|
||||
/// </summary>
|
||||
public void Wait() => _mre.Wait();
|
||||
|
||||
/// <summary>
|
||||
/// 同步等待,并在超时后结束。
|
||||
/// </summary>
|
||||
/// <param name="millisecondsTimeout">等待超时的毫秒数</param>
|
||||
/// <returns>若已触发事件则为 <c>true</c>,否则为 <c>false</c></returns>
|
||||
public bool Wait(int millisecondsTimeout) => _mre.Wait(millisecondsTimeout);
|
||||
|
||||
/// <summary>
|
||||
/// 同步等待,并在超时后结束。
|
||||
/// </summary>
|
||||
/// <param name="timeout">等待超时</param>
|
||||
/// <returns>若已触发事件则为 <c>true</c>,否则为 <c>false</c></returns>
|
||||
public bool Wait(TimeSpan timeout) => _mre.Wait(timeout);
|
||||
|
||||
/// <summary>
|
||||
/// 同步等待,并传递用于结束等待的取消信号。
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">用于结束等待的取消信号</param>
|
||||
public void Wait(CancellationToken cancellationToken) => _mre.Wait(cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// 触发事件。
|
||||
/// </summary>
|
||||
public void Set()
|
||||
{
|
||||
lock (_syncLock)
|
||||
{
|
||||
_tcs.TrySetResult(true); // Use TrySetResult to avoid exceptions on repeated Set
|
||||
_mre.Set();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重置事件。
|
||||
/// </summary>
|
||||
public void Reset()
|
||||
{
|
||||
lock (_syncLock)
|
||||
{
|
||||
if (!_tcs.Task.IsCompleted) return; // already reset
|
||||
_tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
_mre.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed) return;
|
||||
_mre.Dispose();
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user