长时间 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 路径吗?我的直觉告诉我去做,但我的脑袋无法理解为什么......
谢谢!