1

長年の 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 パスをたどる必要があるのか​​を教えてもらえますか? 私の腸はそれをするように言いますが、私の頭はその理由を理解できません...

ありがとう!

4

1 に答える 1

1

ChannelFactory通常、[サービス参照の追加]を使用していない場合に使用されます。つまり、WSDL 経由で生成されていない共有アセンブリ経由で契約を結んでいます。基本的に、バックグラウンドで WCF チャネルを作成するサービス参照の使用を追加します。ClientBase

REST フル サービスを扱う場合WebChannelFactory、共有アセンブリ コントラクトに基づくサービス クライアントのようなインターフェイスを提供します。サービスが REST-ful エンドポイント バインディングのみをサポートしている場合は、[サービス参照の追加] を使用できません。

唯一の違いは好みです。カスタム動作、バインディングなどのためにチャネルに完全にアクセスする必要がありますか。それとも、サービス参照の追加+ SOAP が必要なインターフェイスを十分に提供してくれますか。

于 2012-04-18T20:41:05.253 に答える