Rep*_*Man 10 wcf singleton static-constructor thread-safety channelfactory
在我们的SharePoint/ASP.NET环境中,我们有一系列数据检索器类,这些类都来自通用接口.我被分配了创建数据检索器的任务,该数据检索器可以使用WCF与其他SharePoint场远程通信.我现在实现它的方式ChannelFactory<T>是在静态构造函数中创建单例,然后由远程数据检索器的每个实例重用,以创建单独的代理实例.我认为这样可以很好地工作,因为那时ChannelFactory只在app域中实例化一次并且它的创建保证是线程安全的.我的代码看起来像这样:
public class RemoteDataRetriever : IDataRetriever
{
protected static readonly ChannelFactory<IRemoteDataProvider>
RequestChannelFactory;
protected IRemoteDataProvider _channel;
static RemoteDataRetriever()
{
WSHttpBinding binding = new WSHttpBinding(
SecurityMode.TransportWithMessageCredential, true);
binding.Security.Transport.ClientCredentialType =
HttpClientCredentialType.None;
binding.Security.Message.ClientCredentialType =
MessageCredentialType.Windows;
RequestChannelFactory =
new ChannelFactory<IRemoteDataProvider>(binding);
}
public RemoteDataRetriever(string endpointAddress)
{
_channel = RemoteDataRetriever.RequestChannelFactory.
CreateChannel(new EndpointAddress(endpointAddress));
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,这是一个很好的设计吗?我想,一旦ChannelFactory创建,我不需要担心线程安全,因为我只是用它来打电话,CreateChannel()但我错了吗?它是在改变状态还是在幕后做一些可能导致线程问题的时髦的东西?另外,我是否需要在某个地方放置一些代码(静态终结器?)来手动处理ChannelFactory或者我可以假设每当IIS重新启动它时,它会为我做所有的清理工作吗?
从“这个单例设计好不好”来看,你的单例实现很好。它是线程安全的,并且ChannelFactory<T>也是线程安全的。
您也不必担心资源清理。假设ChannelFactory<T>遵循Microsoft 的 IDisposable 实现指南,那么您不会遇到某种泄漏问题。当应用程序域被拆除时,将创建垃圾收集,此时所有内容都将被清理。终结器 onChannelFactory<T>将执行通常在调用 Dispose 时执行的清理操作。
然而,从“我应该缓存ChannelFactory<T>”的角度来看,很难说,因为你没有指出你使用的 .NET 版本。但是,您指出的文章表明,如果您使用 .NET 3.0 SP1 或更高版本,您实际上不需要这样做,您可以ClientBase<T>在客户端代码中需要的地方创建代理(假设它们派生自 ),而不是通过这样的工厂模式。
| 归档时间: |
|
| 查看次数: |
10176 次 |
| 最近记录: |