0

私の質問に対する適切な回答が数時間で見つからなかったので、ここに投稿します。

共有インターフェイス (IService) ライブラリと動的に作成されたプロキシ (CreateChannel で作成) を備えた WPF/WCF アプリケーションがあります。主な問題は、プロキシが閉じられていない/破棄されていないことであり、200 回目のサービス呼び出しでこの例外が発生しています。

システムは、スロットル 'MaxConcurrentSessions' に設定された制限に達しました。このスロットルの制限は 200 に設定されました。スロットル値は、serviceThrottle 要素の属性「maxConcurrentSessions」を変更するか、動作 ServiceThrottlingBehavior の「MaxConcurrentSessions」プロパティを変更することで変更できます。

興味深いことに、同じプロキシが BasicHttpBinding で正常に動作します!

NetNamedPipeBinding プロキシが閉じられず、自動的に破棄されないようです。クライアント側のコード スニペットを次に示します。

// creation of ChannelFactory - only one for each service interface
public static ChannelFactory<T> CreateChannelFactory(string serviceAddress)
{
    Binding binding = new NetNamedPipeBinding()
    {
        // setting quotas and timeouts                
    };            

    ChannelFactory<T> factory = new ChannelFactory<T>(binding, new EndpointAddress(serviceAddress));

    factory.Endpoint.Behaviors.Add(new AuthenticationBehavior()); // custom IEndpointBehavior

    foreach (OperationDescription op in factory.Endpoint.Contract.Operations)
    {
        DataContractSerializerOperationBehavior dataContractBehavior = op.Behaviors.Find<DataContractSerializerOperationBehavior>() as DataContractSerializerOperationBehavior;
        if (dataContractBehavior != null)
        {
            dataContractBehavior.MaxItemsInObjectGraph = 2147483647;
        }
    }                                     

    return factory;
}

public static T GetService()
{
    // simplified - actually holding a collection of CFs and creating each factory only once
    return ChannelFactoryHelper<T>.CreateChannelFactory(serviceAddress).CreateChannel();
}

// creation of the proxy - new for each WCF call
IService svc = ServiceHelper<IService>.GetService();    
... // calling the service

プロキシは IDisposable を実装していないため、"using" ステートメントを使用していないことがわかります。最初の質問は、どうすればよいかということです。クライアント側では、IService をプロキシ タイプとして使用しています。IService を IDisposable にしたい場合は、サービスが IService を実装しているため、サービス側で dispose メソッドを実装する必要があります。それは論理的ではないようです-サービスメソッドを呼び出してそのサービスを破棄する...

サービス呼び出しのすべてのコードを「使用中」に変更しない方がよいため、使用されなくなったときにプロキシを自動的に破棄する方法はありますか? それが自動的に行われないのはなぜですか?カスタム IExtensionBehavior を使用していることに注意してください - それが理由でしょうか?

どんな助けでも大歓迎です。ありがとうございました!

4

1 に答える 1

0

CreateChannelまず、メソッドから返されたサービス プロキシ オブジェクトが を実装していることがわかります。これは、 が から派生しているIDisposableためです。ただし、これを活用するために標準の using ブロックを使用しないでください。これは、使用中にチャネルに障害が発生した場合、診断が難しい例外が閉じ括弧で発生する可能性があるためです。IClientChannelIDisposable

おそらく、次のパターンのいくつかの変形は、すべてのサービス プロキシ タイプのラッパーで IDisposable を明示的に実装するのに比べて改善される場合があります。デリゲート ( ) を受け入れるジェネリック関数でパターンを実装しAction<IService>て、「サービスの呼び出し」ビットを実行できます。

IService svc;
try
{
    // creation of the proxy - new for each WCF call
    svc = ServiceHelper<IService>.GetService();    
... // calling the service
    myDelegateDoingStuffWithService(svc);
}
finally
{
    try
    {
        ((ICommunicationObject)svc).Close();
    }
    catch (CommunicationException ex)
    {
        ((ICommunicationObject)svc).Abort();
    }
}
于 2013-08-15T15:29:22.377 に答える