13

1 つのClientBase<T>インスタンスが複数の WCF サービス呼び出しに使用されると、チャネルが障害状態になる可能性があります (つまり、サービスがダウンしている場合)。

サービスが再開されたときに、チャネルを自動的に修復したいと考えています。私が見つけた唯一の方法は、各メソッド呼び出しの前に次のコードを呼び出すことです。

if (clientBase.InnerChannel.State == CommunicationState.Faulted)
{
      clientBase.Abort();
      ((IDisposable)clientBase).Dispose();
      clientBase = new SampleServiceClientBase();
}

これは正しいやり方ではないと感じました。誰かがより良いアイデアを得ましたか?

4

2 に答える 2

21

できません。チャネルに障害が発生すると、それは完全に障害になります。新しいチャネルを作成する必要があります。WCF チャネルは (いわば) ステートフルであるため、障害のあるチャネルは状態が破損している可能性があることを意味します。

できることは、使用しているロジックをユーティリティ メソッドに入れることです。

public static class Service<T> where T : class, ICommunicationObject, new()
{
    public static void AutoRepair(ref T co)
    {
        AutoRepair(ref co, () => new T());
    }

    public static void AutoRepair(ref T co, Func<T> createMethod)
    {
        if ((co != null) && (co.State == CommunicationState.Faulted))
        {
            co.Abort();
            co = null;
        }
        if (co == null)
        {
            co = createMethod();
        }
    }
}

次に、次の方法でサービスを呼び出すことができます。

Service<SampleServiceClient>.AutoRepair(ref service,
    () => new SampleServiceClient(someParameter));
service.SomeMethod();

または、デフォルトのパラメーターなしのコンストラクターを使用する場合は、次のようにします。

Service<SampleServiceClient>.AutoRepair(ref service);
service.SomeMethod();

サービスが の場合も処理するため、null呼び出す前にサービスを初期化する必要はありません。

私が提供できる最高のものです。たぶん、他の誰かがより良い方法を持っています。

于 2010-01-05T19:32:18.533 に答える
1

これは私が現在行っていることですが、これが最善の選択肢であるとは言えません。

呼び出しで例外がキャッチされたときに、プロキシを再作成します。

try
{
    ListCurrentProcesses();
}
catch (TypeLoadException ex)
{
    Debug.Print("Oops: " + ex.Message);
    m_Proxy = new ProcessManagerProxy();
}
catch (EndpointNotFoundException endpointEX)
{
    Debug.Print("Oops: " + endpointEX.Message);
    m_Proxy = new ProcessManagerProxy();
}
catch (CommunicationException communicationEx)
{
    Debug.Print("Oops: " + communicationEx.Message);
    m_Proxy = new ProcessManagerProxy();
}
于 2010-01-05T19:45:59.080 に答える