WCF 客户端代理,ASP.Net 中的客户端/通道缓存 - 代码审查



很长一段时间 ASP.Net 界面开发人员被要求学习WCF,寻找更多与架构相关的方面的教育 - 因为这不是我的强项,但我必须处理。

在我们当前的ASMX世界中,我们采用了创建ServiceManager静态类的模型,用于与Web服务的交互。 我们开始迁移到 WCF,尝试遵循相同的模型。 起初我正在处理性能问题,但我已经调整了一些,我们现在运行顺利,但我质疑我的策略。 以下是我们正在做的事情的简化版本(删除了错误处理、缓存、对象操作等):

public static class ContentManager
{
    private static StoryManagerClient _clientProxy = null;
    const string _contentServiceResourceCode = "StorySvc";
    // FOR CACHING
    const int _getStoriesTTL = 300;
    private static Dictionary<string, GetStoriesCacheItem> _getStoriesCache = new Dictionary<string, GetStoriesCacheItem>();
    private static ReaderWriterLockSlim _cacheLockStories = new ReaderWriterLockSlim();
    public static Story[] GetStories(string categoryGuid)
    {
        // OMITTED - if category is cached and not expired, return from cache
        // get endpoint address from FinderClient (ResourceManagement SVC)
        UrlResource ur = FinderClient.GetUrlResource(_contentServiceResourceCode);
        // Get proxy
        StoryManagerClient svc = GetStoryServiceClient(ur.Url);
        // create request params
        GetStoriesRequest request = new GetStoriesRequest{}; // SIMPLIFIED
        Manifest manifest = new Manifest{}; // SIMPLIFIED
        // execute GetStories at WCF service
        try
        {
            GetStoriesResponse response = svc.GetStories(manifest, request);
        }
        catch (Exception)
        {
            if (svc.State == CommunicationState.Faulted)
            {
                svc.Abort();
            }
            throw;
        }
        // OMITTED - do stuff with response, cache if needed
        // return....
    }
    internal static StoryManagerClient GetStoryServiceClient(string endpointAddress)
    {
        if (_clientProxy == null)
            _clientProxy = new StoryManagerClient(GetServiceBinding(_contentServiceResourceCode), new EndpointAddress(endpointAddress));
        return _clientProxy;
    }
    public static Binding GetServiceBinding(string bindingSettingName)
    {
        // uses Finder service to load a binding object - our alternative to definition in web.config
    }
    public static void PreloadContentServiceClient()
    {
        // get finder location
        UrlResource ur = FinderClient.GetUrlResource(_contentServiceResourceCode);
        // preload proxy
        GetStoryServiceClient(ur.Url);
    }    
}

我们现在运行平稳,往返通话在 100 毫秒范围内完成。 创建 PreloadContentServiceClient() 方法并添加到我们的 global.asax 中,将"首次调用"性能降低到相同的水平。您可能想知道我们正在使用 DataContractSerializer 和"添加服务引用"方法。

我已经阅读了很多关于静态类、单例、共享数据协定程序集、如何使用 ChannelFactory 模式以及我可以对我们的使用模型执行的一大堆其他事情......诚然,有些事情超出了我的脑海。 而且,就像我说的,我们似乎运行顺利。 不过,我知道我没有看到大局。 有人可以告诉我我在通道池、代理故障等方面最终得到了什么,以及为什么我应该走 ChannelFactory 的道路? 我的直觉说就去做,但我的头脑无法理解为什么......

谢谢!

ChannelFactory通常在

不使用"添加服务引用"时使用 - 您通过共享程序集而不是通过 WSDL 生成的协定。添加服务引用使用ClientBase实质上是在后台创建 WCF 通道。

当您处理 REST ful 服务时,WebChannelFactory 提供了一个基于共享程序集协定的服务客户端接口。如果服务仅支持 REST 终结点绑定,则无法使用"添加服务引用"。

唯一的区别是首选项 - 您是否需要完全访问自定义行为、绑定等的通道,或者添加服务引用 + SOAP 是否为您提供了足够的接口以满足您的需求。

最新更新