是否有必要清理 SocketAsyncEventArgs.Completed?
Posted
技术标签:
【中文标题】是否有必要清理 SocketAsyncEventArgs.Completed?【英文标题】:Is it necessary to clean up the SocketAsyncEventArgs.Completed? 【发布时间】:2014-11-24 05:16:26 【问题描述】:所以我有一个带有 SocketAsyncEventArgs
池的 IOCP 项目,这使得它们可以重复使用并减少了 SocketAsyncEventArgs.
的繁重分配任务
我假设当 SocketAsyncEventArgs.Completed 事件被调用时,保持可重用(未释放),链中挂钩的 Completed 事件不会自动设置为 null。 因此,如果我不想多次触发特定事件,我必须手动清理事件。
我对 SocketAsyncEventArgs.Completed 的假设是否正确?还是在某种程度上是内部管理的?
下面的代码可能解释的更清楚:
void Foo(SocketAsyncEventArgs e) // Call-back
DoJob(e);
// Should I do it?
// e.Completed -= Foo;
提前致谢。
【问题讨论】:
我对此一无所知,但由于没有其他人回答或评论:整个设计容易出现时序漏洞。如果您确实需要从 e.Completed 中删除事件处理程序以避免不必要的多次调用,那么您应该在调用 DoJob() 之前执行它,而不是之后。但即便如此,也可能存在时间漏洞。无论如何,这是现在开源的 .Net 的一部分吗?如果是这样,您可以在那里找到答案。 谢谢。可能我宁愿考虑更稳定的设计,我不必担心这样的事情,而不是尝试清除 Completed 事件。赞赏。 【参考方案1】:使用SocketAsyncEventArgs
类的正确方法是在创建实例时添加处理程序一次。完成后,您只需将实例返回到池中。您不需要删除处理程序;当您从池中提取新实例时,您只是不要再次添加处理程序。
不要忘记还有其他字段(即与您正在处理的特定完成相关的字段)您确实希望清除这些字段。完成当前操作后,您可以在将实例返回池之前清除它们,或者您可以等到下次使用它时从池中检索实例。恕我直言,最好在将值返回池之前清除这些值,因为对于引用类型值,如果它们不再在其他地方使用,将确保对象是可收集的,而不是从池中获得“幻像”引用以保持它们可访问。
【讨论】:
以上是关于是否有必要清理 SocketAsyncEventArgs.Completed?的主要内容,如果未能解决你的问题,请参考以下文章