在我们的SharePoint / ASP.NET环境中,我们有一系列数据检索器类,这些类都来自通用接口。我被分配了创建数据检索器的任务,该数据检索器可以使用WCF与其他SharePoint场远程通信。我现在实现它的方式是在静态构造函数中创建单例ChannelFactory<T>
,然后由远程数据检索器的每个实例重用以创建单独的代理实例。我认为这样可以正常运行,因为ChannelFactory
只能在应用程序域中实例化一次,并且其创建为guaranteed to be thread-safe。我的代码看起来像这样:
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));
}
}
我的问题是,这是一个好设计吗?我认为一旦ChannelFactory
被创建,我不需要担心线程安全,因为我只是用它来调用CreateChannel()
但是我错了?它是在改变状态还是在幕后做一些可能导致线程问题的时髦的东西?另外,我是否需要在某个地方放置一些代码(静态终结器?)来手动处理ChannelFactory
,或者我可以假设每当IIS重新启动它时,它会为我做所有的清理工作吗?
答案 0 :(得分:3)
从“这单身设计好”这个单身人士的实现就可以了。它是线程安全的,ChannelFactory<T>
也是线程安全的。
您也不必担心资源清理。假设ChannelFactory<T>
跟Microsoft's guidelines for implementing IDisposable之后,那么你就不会遇到某种泄漏的问题。当应用程序域被拆除时,将创建垃圾收集,并且此时将清除所有。 ChannelFactory<T>
上的终结器将执行通常在调用Dispose时执行的清理。
但是,从“我应该缓存ChannelFactory<T>
”的角度来看,很难说,因为你没有说明你所使用的.NET版本。但是,您指出的文章表明,如果您使用的是.NET 3.0 SP1或更高版本,您实际上不需要这样做,您可以创建代理(假设它们来自ClientBase<T>
)您需要它的地方在客户端代码中,而不是通过像这样的工厂模式。
答案 1 :(得分:0)
只要您的“单身人士”只是简单地返回新构建的频道,您就不必担心线程安全。如果你愿意的话,你总是可以在静态声明上抛出volatile关键字,以防止任何可能破坏你的编译器优化,但我不认为在这种情况下是必要的。
试着问自己有关长期灵活性的问题。例如,如果您稍后决定在此CreateChannel方法中添加一些状态,该怎么办?也许它会像创建多达10个频道一样,然后在此之后开始重新使用它们。你能轻易修改你的单身人士吗?
你的回答可能是肯定的,但如果你然后垂直扩展到多个服务器怎么办?单身可能还不够。您需要某种方式在实例/服务器(例如,数据库,分布式缓存)之间共享状态;在静态环境中可能很难做到,这取决于你决定分享状态的方式。
答案 2 :(得分:0)
I this article,Daniel Vaughan主张在Singleton管理器对象中缓存Channels,但从不缓存ChannelFactory。到目前为止,我们一直在使用这种方法没有成功...
这样做的好处是:
“当频道进入故障状态时,它会从缓存中删除,并在下次请求时重新创建......”