Files
MoShiro/backend/shared/Monitor.Measurement/Core/RunningBlock.cs
T
2026-10-04 21:46:39 +08:00

48 lines
1.6 KiB
C#

namespace Monitor.Measurement;
/// <summary>一个运行中的积木:自己的取消令牌和后台任务。Probe 和 Agent 共用。</summary>
public sealed class RunningBlock : IDisposable
{
private readonly CancellationTokenSource _cts = new();
private RunningBlock(IBlock block, string signature)
{
Block = block;
Signature = signature;
Completion = Task.CompletedTask;
}
public IBlock Block { get; }
/// <summary>参数、端口或流编号变化时调和器据此重启积木。</summary>
public string Signature { get; }
/// <summary>积木自己结束(单向数据流的发送端)或失败(<see cref="BlockFaultException"/>)时完成;被 <see cref="StopAsync"/> 停止时正常完成。</summary>
public Task Completion { get; private set; }
public static RunningBlock Start(IBlock block, string signature)
{
var running = new RunningBlock(block, signature);
running.Completion = Task.Run(() => block.RunAsync(running._cts.Token), CancellationToken.None);
return running;
}
/// <summary>停止积木并等它退出(最多 5 秒)。</summary>
public async Task StopAsync()
{
await _cts.CancelAsync();
try
{
await Completion.WaitAsync(TimeSpan.FromSeconds(5));
}
catch (Exception ex) when (ex is OperationCanceledException or TimeoutException or BlockFaultException)
{
// 没有及时退出或者已经失败:不再等
}
Dispose();
}
public void Dispose() => _cts.Dispose();
}