gpt4 book ai didi

c# - 简单的注入(inject)器 - 导致容器不被垃圾收集的装饰器?

转载 作者:行者123 更新时间:2023-11-30 16:05:45 26 4
gpt4 key购买 nike

我注意到当我通过简单的注入(inject)器添加装饰器时,容器不会超出范围。有谁知道这是否是预期的?如果我不添加装饰器,容器就会被垃圾回收。否则,它不是。我应该做些什么来强制清理?

这是一个简单的例子。如果添加了装饰器,则在“运行”完成后容器仍在内存中。如果不添加装饰器,容器将被 GC 处理。

public interface IDoSomething { }
public class DoSomething: IDoSomething { }
public class DoSomethingDec1: IDoSomething {
public DoSomethingDec1(IDoSomething handler) { }
}
public class DoSomethingDec2 : IDoSomething {
public DoSomethingDec2(IDoSomething handler) { }
}

static void Main(string[] args) {
Console.WriteLine("Press a key to start");
Console.ReadKey(true);
Run();
GC.Collect();
Console.WriteLine("Done");
Console.ReadKey(true);
}

static void Run() {
//can be re-created with 1 container; easier to see with multiple
for (var i = 0; i < 1000; i++) {
using (var container = new Container()) {
container.Register<IDoSomething, DoSomething>();

//Comment out these 2 lines to remove the decorators
container.RegisterDecorator<IDoSomething, DoSomethingDec1>();
container.RegisterDecorator<IDoSomething, DoSomethingDec2>();

container.Verify();

container.GetInstance<IDoSomething>();
}
}
}

使用装饰器:

enter image description here

没有装饰器:

enter image description here

最佳答案

更新:此问题已在 v3.1.1 中修复.

问题是由 bug in the .NET framework 引起的如果图形包含 ThreadLocal<T>,则使循环对象图保持事件状态.对于 Simple Injector,装饰器子系统添加了一个 ThreadLocal<T>。到 ContainerItems字典。 ThreadLocal的值间接引用 Container再次,导致图形变得循环。由于 .NET 中的错误,ThreadLocal<T>被认为是活着的,保留其依赖对象,例如 Container活。 Container instance 再次使其他一切保持事件状态,这显然会导致内存泄漏。

虽然我们可以等待 Microsoft 修复此问题,但这可能需要很长时间。所以我们的计划是在未来的补丁版本中解决这个问题。我们可能会替换 .NET 的 ThreadLocal<T>使用我们自己的不会导致内存泄漏的自定义实现。此自定义实现已在 Simple Injector 的 PCL 库中使用,因为 ThreadLocal<T>不适用于 PCL。这意味着 Simple Injector 的 PCL 版本没有这个问题。

关于c# - 简单的注入(inject)器 - 导致容器不被垃圾收集的装饰器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33156432/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com