WCF服务和IDisposable,我清理托管对象吗?

时间:2010-11-24 08:28:45

标签: wcf

我已经实现了WCF服务:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single, UseSynchronizationContext=false)]
public sealed class SynchronizationService : ISynchronizationService, IDisposable
{
   private MemoryStream objectStream;

   ...
}

ISyncrhonizationService有[ServiceContract(SessionMode = SessionMode.Required)]。

如果客户端正确通信并最终使用[IsTerminating = true]调用方法,那么我可以很好地处理objectStream变量。如果由于某种原因服务和客户端之间的通信中断,我想自己从服务端清理objectStream变量,这就是我想实现IDisposable接口的原因。但是看一下MSDN文档(http://msdn.microsoft.com/en-us/library/system.idisposable.aspx)我对此有点怀疑,因为根据文档:

    // Dispose(bool disposing) executes in two distinct scenarios.
    // If disposing equals true, the method has been called directly
    // or indirectly by a user's code. Managed and unmanaged resources
    // can be disposed.
    // If disposing equals false, the method has been called by the
    // runtime from inside the finalizer and you should not reference
    // other objects. Only unmanaged resources can be disposed.

因为它是调用Dispose方法的运行时,然后处理= false。因此我不应该访问objectStream,因为它是一个托管对象。在这种情况下,运行时提供的SyncrhonizationService终结器应该清理objectStream本身,我根本不需要实现IDisposable。然而,一些论坛帖子建议重新使用SyncrhonizationService实例,而不是处理/最终确定。

所以我的问题是:

1)在例外/故障/超时/等期间,SyncrhonizationService实例实际发生了什么?它会被处置或稍后重复使用吗?

2)我是否需要实现IDisposable并在Dispose()方法中处理托管对象?

3)是否有更好的IDisposable替代品,例如channel_Faulted事件?如果我在这样的事件中处理我的托管对象,我将如何以及在何处删除事件处理程序(我可以在事件处理程序中执行此操作,但如果发生其他类型的异常/错误会怎么样?)

1 个答案:

答案 0 :(得分:20)

如果实现IDisposable,则可以清理Dispose()方法实现中的托管对象。

使用PerSession InstanceContextMode,WCF运行时将在会话结束时调用SynchronisationService对象上的Dispose,无论是因为客户端关闭了他的代理;由于会话超时(通过不活动)(在客户端或服务器上);或通过渠道断层。

不会重用服务实例:新会话将获得SynchronisationService的新实例。