我正在尝试将现有的.NET Remoting应用程序转换为WCF。服务器和客户端都共享公共(public)接口(interface),并且所有对象都是服务器激活的对象。

在WCF世界中,这类似于创建按 call 服务并使用ChannelFactory<T>创建代理。我正在为如何为ASP.NET客户端正确创建ChannelFactory<T>而苦苦挣扎。

出于性能原因,我想缓存ChannelFactory<T>对象,并在每次调用服务时都创建 channel 。在.NET远程处理时代,过去曾经使用RemotingConfiguration.GetRegisteredWellknownClientTypes()方法来获取我可以缓存的客户端对象的集合。看起来,在WCF世界中没有这样的东西,尽管我能够从配置文件中获得端点的集合。

现在,我认为这是可行的。我可以创建这样的东西:

public static ProxyHelper
{
    static Dictionary<Type, object> lookup = new Dictionary<string, object>();

    static public T GetChannel<T>()
    {
        Type type = typeof(T);
        ChannelFactory<T> factory;

        if (!lookup.ContainsKey(type))
        {
            factory = new ChannelFactory<T>();
            lookup.Add(type, factory);
        }
        else
        {
            factory = (ChannelFactory<T>)lookup[type];
        }

        T proxy = factory.CreateChannel();
        ((IClientChannel)proxy).Open();

        return proxy;
    }
}

我认为上面的代码可以工作,但是我有点担心多个线程试图添加新的ChannelFactory<T>对象(如果不在查找中)。由于使用的是.NET 4.0,因此我在考虑使用ConcurrentDictionaryGetOrAdd()方法,或者先使用TryGetValue()方法来检查ChannelFactory<T>是否存在和不存在,然后再使用GetOrAdd()方法。虽然不确定ConcurrentDictionary.TryGetValue()ConcurrentDictionary.GetOrAdd()方法的性能。

另一个小问题是,是否需要在ASP.NET应用程序结束后在 channel 工厂对象上调用ChannelFactory.Close()方法,还是可以让.NET框架自行处理 channel 工厂对象?使用((IChannel)proxy).Close()方法调用服务方法后,代理 channel 将始终关闭。

最佳答案

是的,如果您想创建这样的东西(一个用于容纳所有ChannelFactory<T>实例的静态类),则必须确保该类是100%线程安全的,并且在并发访问时不会出错。我还没有使用过.NET 4的功能,因此我无法对这些功能进行特别评论-但我绝对建议您尽可能地使其安全。

至于您的第二个(次要)问题:ChannelFactory本身是一个静态类-因此您不能真正在其上调用.Close()方法。如果您想询问是否在实际的.Close()上调用IChannel方法,那么再次:是的,请尽力成为一名好公民,并尽可能关闭这些 channel 。如果您错过了一个,.NET将为您提供服务-但不要只是在地板上扔掉您未使用的 channel 然后继续-自己清理一下! :-)

关于c# - 创建WCF ChannelFactory <T>,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3200197/

10-11 23:15