namespace Monitor.Measurement;
/// 一个运行中的积木:自己的取消令牌和后台任务。Probe 和 Agent 共用。
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; }
/// 参数、端口或流编号变化时调和器据此重启积木。
public string Signature { get; }
/// 积木自己结束(单向数据流的发送端)或失败()时完成;被 停止时正常完成。
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;
}
/// 停止积木并等它退出(最多 5 秒)。
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();
}