我们有一个模仿事件的库,并提供一些增强功能。它主要通过跟踪您注册的代表来实现这一点。与事件一样,它有可能发生内存泄漏。
我正在将管理委托的类更改为使用弱引用,但我遇到了一个问题:如果您注册了匿名lambda并且GC.Collect
代理被收集了。我想以编程方式确定注册的委托是否是匿名lambda,并使用强引用代替该情况。
问:如何判断委托是否是匿名lambda(或者更常见的是,语义上我们不希望它会立即消失'。
可能有效的一种方法是检查Delegate.Target
属性是否为null,但这通常会捕获静态方法,因此可能不是我想要的。另一个选项是检查IsSpecialName
属性上的IsStatic
和Delegate.Method
是否设置为true。不确定这是否正确。
一个问题是,如果我使用已注册的类的成员对lambdas进行强引用,我们仍然会遇到相同的内存泄漏情况......或者我们可能会访问已处置的对象。是否有一种优雅的方式来处理这个问题?
答案 0 :(得分:1)
基本上,你不能。在运行时,匿名lambda的是方法。您可以检查方法名称:
static int Foo() { return 0; }
void Main()
{
Func<int> foo = Foo;
Func<int> bar = () => 0;
Console.WriteLine(foo.Method.Name); // Foo
Console.WriteLine(bar.Method.Name); // <Main>b__0
}
这是一个非常糟糕的方法,但它可能是唯一的方法,因为foo
和bar
无法区分。