長年の ASP.Net インターフェイス開発者は、WCF を学ぶように求められ、より多くのアーキテクチャ関連の面での教育を求めていました。
現在の ASMX の世界では、Web サービスとのやり取りのために ServiceManager 静的クラスを作成するモデルを採用しました。同じモデルに従うことを試みて、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 と "Add Service Reference" メソッドを使用していることを知りたいかもしれません。
私は、静的クラス、シングルトン、共有データ コントラクト アセンブリ、ChannelFactory パターンの使用方法、および使用モデルに対して実行できる他の多くのことについて、多くのことを読みました...確かに、そのいくつかは行き過ぎています私の頭。そして、私が言ったように、私たちは順調に進んでいるようです。しかし、全体像が見えていないことはわかっています。チャネル プール、プロキシの失敗などに関して、私がここでどうなったか、また、なぜ ChannelFactory パスをたどる必要があるのかを教えてもらえますか? 私の腸はそれをするように言いますが、私の頭はその理由を理解できません...
ありがとう!