C#工厂创建基于可释放资源的服务时的资源释放方案咨询
解决方案
针对你的场景,以下两个方案分别适配不同的使用需求,同时完全满足「隐藏DisposableIOResource创建逻辑」「资源正确释放」「符合工厂语义」的要求:
方案一:Reader绑定资源生命周期(适合Reader与资源一一对应的场景)
核心思路是让Reader本身实现IDisposable,内部持有并负责释放资源,上层完全感知不到DisposableIOResource的存在,符合封装要求。
// 内部类型,上层调用方完全无法感知 internal class DisposableIOResource : IDisposable { public DisposableIOResource(string configuration) { // 高成本初始化逻辑 } public void Dispose() { // 资源释放逻辑 } } public class Reader : IDisposable { private readonly DisposableIOResource _resource; // 构造函数设为internal,只有同程序集的工厂可以创建,避免上层自行实例化 internal Reader(DisposableIOResource resource) { _resource = resource; } public void DoSomething() { // 使用_resource执行业务逻辑 } public void Dispose() { _resource.Dispose(); } } public class ServiceFactory { public Reader CreateReader(string configuration) { var resource = new DisposableIOResource(configuration); return new Reader(resource); } }
使用方式:
var serviceFactory = new ServiceFactory(); // 遵循.NET原生using约定,离开作用域自动释放资源 using var reader = serviceFactory.CreateReader(configuration); reader.DoSomething();
方案二:内置资源池(适合高频调用、需要降低高成本资源创建开销的场景)
如果DisposableIOResource是线程安全可复用的,可在工厂层内置资源池,统一管理资源的创建、复用、释放,进一步降低性能损耗。
public class ServiceFactory : IDisposable { private readonly ConcurrentQueue<DisposableIOResource> _resourcePool = new(); private readonly string _configuration; private bool _isDisposed; // 全局只需要初始化一次工厂即可 public ServiceFactory(string globalConfiguration) { _configuration = globalConfiguration; } public Reader CreateReader() { // 优先复用池内空闲资源,没有空闲资源才新建 if (!_resourcePool.TryDequeue(out var resource)) { resource = new DisposableIOResource(_configuration); } return new Reader(resource, ReturnResourceToPool); } private void ReturnResourceToPool(DisposableIOResource resource) { // 工厂已释放则直接释放资源,否则校验有效性后回池 if (_isDisposed) { resource.Dispose(); return; } // 可在此处加资源有效性校验,无效资源直接释放不回池 _resourcePool.Enqueue(resource); } public void Dispose() { _isDisposed = true; // 工厂释放时统一销毁所有池内资源 while (_resourcePool.TryDequeue(out var resource)) { resource.Dispose(); } } } public class Reader : IDisposable { private readonly DisposableIOResource _resource; private readonly Action<DisposableIOResource> _returnCallback; private bool _isDisposed; internal Reader(DisposableIOResource resource, Action<DisposableIOResource> returnCallback) { _resource = resource; _returnCallback = returnCallback; } public void DoSomething() { // 执行业务逻辑 } public void Dispose() { if (_isDisposed) return; _isDisposed = true; _returnCallback(_resource); } }
使用方式:
// 全局初始化一次工厂 using var serviceFactory = new ServiceFactory(globalConfiguration); // 多次创建Reader都会复用池内资源,不会重复执行高成本初始化逻辑 for (var i = 0; i < 100; i++) { using var reader = serviceFactory.CreateReader(); reader.DoSomething(); }
内容的提问来源于stack exchange,提问作者gio
相关产品推荐
相关产品推荐

