C# 在Silverlight中调用方法后,是否有理由从事件中删除该方法?
最近,我遇到越来越多的人,他们的代码与以下类似:C# 在Silverlight中调用方法后,是否有理由从事件中删除该方法?,c#,silverlight,events,C#,Silverlight,Events,最近,我遇到越来越多的人,他们的代码与以下类似: private AsynchronousReader r; public SynchronousReader() { r = new AsynchronousReader(); // My practice is to put this here // and then never remove it and never add it again // thus cleaning up the code and
private AsynchronousReader r;
public SynchronousReader()
{
r = new AsynchronousReader();
// My practice is to put this here
// and then never remove it and never add it again
// thus cleaning up the code and preventing constant add/remove.
//r.ReadCompleted += this.ReadCompletedCallback;
}
private ReadCompletedCallback()
{
// Remove the callback to "clean things up"...
r.ReadCompleted -= this.ReadCompletedCallback;
// Do other things
}
public Read()
{
r.ReadCompleted += this.ReadCompletedCallback;
// This call completes asynchronously and later invokes the above event
r.ReadAsync();
r.WaitForCompletion();
}
人们说这种做法比我上面提到的要好,并给出了Silverlight的几个具体原因。他们说它可以防止内存泄漏、线程问题,甚至是正常的做法
我没有做过很多Silverlight,但仍然这样做似乎很愚蠢。
在对象的生命周期内,使用此方法而不只是在构造函数中装配回调有什么具体原因吗
这是我能举的最简单的例子。忽略这样一个事实:它是一种将异步对象转换为同步对象的包装器。我只是好奇事件的添加和删除方式。在您提到的情况下,将其连接一次是有意义的,但由于事件处理程序仍然引用对象,因此对象(父对象和/或子对象)可能不会被垃圾收集 据 i、 e.如果我们有:
publisher.SomeEvent += target.SomeHandler;
然后“publisher”将使“target”保持活动状态,但“target”将不保持活动状态
“出版商”活着
要记住的更重要的一点可能是子对象的寿命如果与父级相同,则构造函数中的一次性订阅更有意义。如果是动态的,您可能希望删除处理程序,因为我看到它们泄漏(导致多个回调)
注意:如果只使用构造函数的方法结果是泄漏对象,我想您可以在
Dispose()
中取消订阅,但我不能说我见过这样的情况。听起来您有两个问题:
第三种解决方案可能是:保留SynchronousReader的单个实例,但每次调用SynchronousReader.Read都会创建AsynchronousReader的新实例(而不是将其存储为实例中的私有字段)。然后,您可以保留大部分您不喜欢的代码,但这些代码可以正确处理事件订阅。将
r.ReadCompleted+=this.ReadCompletedCallback代码>在构造函数中?他不会订阅Read()中的事件,正常情况下,我还是会读的@HiTechMagic:在我看来,他通常订阅构造函数,从不退订。未注释掉的代码是他在其他人编写的代码中发现的。问题是,将其放入构造函数还是将其留在被调用的方法中是最佳做法,然后调用一个单独的异步方法,并在调用回调后将其删除。我刚才提到的一点是,如果按照这里实现的方式执行,那么两个异步调用竞相完成将失败,如果一个在另一个之前完成,那么回调将在刚刚完成的回调中被删除。注释掉的代码是我想要使用的实践,在我看来,实现后的代码是糟糕/混乱的东西。我的问题(在底部)表明包装器是不相关的。