GFramework/GFramework.Cqrs.Benchmarks/Messaging/BenchmarkCleanupHelper.cs
gewuyou 3233151207 fix(ioc): 修复容器释放竞态与清理路径
- 修复 MicrosoftDiContainer 在等待线程与并发 Dispose 场景下泄露底层锁异常的问题
- 更新 IIocContainer 释放契约文档并移除 Clear 中不可达的 provider 释放逻辑
- 新增 benchmark cleanup helper、并发释放回归测试与 ai-plan 恢复入口
2026-05-06 20:23:16 +08:00

58 lines
1.7 KiB
C#

// Copyright (c) 2025-2026 GeWuYou
// SPDX-License-Identifier: Apache-2.0
using System;
using System.Collections.Generic;
using System.Runtime.ExceptionServices;
namespace GFramework.Cqrs.Benchmarks.Messaging;
/// <summary>
/// 统一处理 benchmark 宿主的资源释放,避免前一个 <see cref="IDisposable" /> 抛错后中断后续清理。
/// </summary>
internal static class BenchmarkCleanupHelper
{
/// <summary>
/// 按顺序释放一组 benchmark 资源,并在全部资源都尝试释放后再回抛异常。
/// </summary>
/// <param name="disposables">当前 benchmark 宿主拥有并负责释放的资源。</param>
/// <exception cref="Exception">
/// 当且仅当至少一个资源释放失败时抛出。
/// 单个失败会回抛原始异常,多个失败会聚合为 <see cref="AggregateException" />。
/// </exception>
public static void DisposeAll(params IDisposable?[] disposables)
{
List<Exception>? exceptions = null;
foreach (var disposable in disposables)
{
if (disposable is null)
{
continue;
}
try
{
disposable.Dispose();
}
catch (Exception exception)
{
exceptions ??= [];
exceptions.Add(exception);
}
}
if (exceptions is null)
{
return;
}
if (exceptions.Count == 1)
{
ExceptionDispatchInfo.Capture(exceptions[0]).Throw();
}
throw new AggregateException("One or more benchmark resources failed to dispose cleanly.", exceptions);
}
}