创建单个ChannelFactory <T>并重用客户端连接

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重用策略

cas*_*One 4

从“这个单例设计好不好”来看,你的单例实现很好。它是线程安全的,并且ChannelFactory<T>也是线程安全的。

您也不必担心资源清理。假设ChannelFactory<T>遵循Microsoft 的 IDisposable 实现指南,那么您不会遇到某种泄漏问题。当应用程序域被拆除时,将创建垃圾收集,此时所有内容都将被清理。终结器 onChannelFactory<T>将执行通常在调用 Dispose 时执行的清理操作。

然而,从“我应该缓存ChannelFactory<T>”的角度来看,很难说,因为你没有指出你使用的 .NET 版本。但是,您指出的文章表明,如果您使用 .NET 3.0 SP1 或更高版本,您实际上不需要这样做,您可以ClientBase<T>在客户端代码中需要的地方创建代理(假设它们派生自 ),而不是通过这样的工厂模式。