我已经实现了WCF服务,例如:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single, UseSynchronizationContext=false)]
public sealed class SynchronizationService : ISynchronizationService, IDisposable
{
private MemoryStream objectStream;
...
}
ISyncrhonizationService具有[ServiceContract(SessionMode = SessionMode.Required)]。
如果客户端正确通信,并最终使用[IsTerminate = 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方法,然后dispose = false。因此,我不应该访问objectStream,因为它是一个托管对象。在这种情况下,运行时提供的SyncrhonizationService终结器应清除objectStream本身,而我根本不需要实现IDisposable。然而,一些论坛帖子建议SyncrhonizationService实例将被重用,并且不会被处理/最终化。
所以我的问题是:
1)在异常/故障/超时/等期间,SyncrhonizationService实例实际发生了什么?它会被处置还是稍后再使用?
2)我是否需要实现IDisposable并在Dispose()方法中处理托管的objetcs?
3)也许有更好的替代IDisposable的方法,例如channel_Faulted事件?如果确实在这样的事件中处理托管对象,我将如何以及在何处删除事件处理程序(我可以在事件处理程序中执行此操作,但是如果发生另一种类型的异常/故障该怎么办)?
最佳答案
如果实现IDisposable,则可以在Dispose()方法的实现内清理托管对象。
使用PerSession InstanceContextMode,无论会话是由于客户端关闭了代理,还是在会话结束时,WCF运行时都将在SynchronisationService对象上调用Dispose。由于会话因不活动而超时(在客户端或服务器上);或通过通道故障。
该服务实例将不会被重用:新的会话将获得SynchronisationService的新实例。
关于wcf - WCF服务和IDisposable,我是否清理托管对象?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4264746/