2

WCF デュプレックス設定でクライアントのコールバック メソッドでスローされた例外を処理するにはどうすればよいですか?

現在、クライアントは障害イベントを発生させないように見えますが (誤って監視していない限り?)、その後クライアントを使用して Ping() を呼び出すと、次の CommunicationException で失敗します: "通信オブジェクト、System.ServiceModel.Channels.ServiceChannel 、中断されたため、通信に使用できません。」.

これに対処し、クライアントなどを再作成するにはどうすればよいですか? 私の最初の質問は、それがいつ起こるかを知る方法です。第二に、どのように対処するのが最善ですか?

私のサービスとコールバック コントラクト:

[ServiceContract(CallbackContract = typeof(ICallback), SessionMode = SessionMode.Required)]
public interface IService
{
    [OperationContract]
    bool Ping();
}

public interface ICallback
{
    [OperationContract(IsOneWay = true)]
    void Pong();
}

私のサーバーの実装:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class Service : IService
{
    public bool Ping()
    {
        var remoteMachine = OperationContext.Current.GetCallbackChannel<ICallback>();

        remoteMachine.Pong();
    }
}

私のクライアントの実装:

[CallbackBehavior(UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Single)]
public class Client : ICallback
{
    public Client ()
    {
        var context = new InstanceContext(this);
        var proxy = new WcfDuplexProxy<IApplicationService>(context);

        (proxy as ICommunicationObject).Faulted += new EventHandler(proxy_Faulted);

        //First Ping will call the Pong callback. The exception is thrown
        proxy.ServiceChannel.Ping();
        //Second Ping call fails as the client is in Aborted state
        try
        {
            proxy.ServiceChannel.Ping();
        }
        catch (Exception)
        {
            //CommunicationException here 
            throw;
        }
    }
    void Pong()
    {
        throw new Exception();
    }

    //These event handlers never get called
    void proxy_Faulted(object sender, EventArgs e)
    {
        Console.WriteLine("client faulted proxy_Faulted");
    }
}
4

1 に答える 1

1

結局のところ、Faulted イベントが発生することは期待できません。したがって、接続を再確立する最善の方法は、その後の Ping() の呼び出しが失敗したときに行うことです。

ここではコードを単純にします。

public class Client : ICallback
{
    public Client ()
    {
        var context = new InstanceContext(this);
        var proxy = new WcfDuplexProxy<IApplicationService>(context);

        (proxy.ServiceChannel as ICommunicationObject).Faulted +=new EventHandler(ServiceChannel_Faulted);

        //First Ping will call the Pong callback. The exception is thrown
        proxy.ServiceChannel.Ping();
        //Second Ping call fails as the client is in Aborted state
        try
        {
            proxy.ServiceChannel.Ping();
        }
        catch (Exception)
        {
            //Re-establish the connection and try again
            proxy.Abort();
            proxy = new WcfDuplexProxy<IApplicationService>(context);
            proxy.ServiceChannel.Ping();
        }
    }
    /*
    [...The rest of the code is the same...]
    //*/
}

明らかに、私のコード例では例外が再びスローされますが、これが接続を再確立する方法を人々に知らせるのに役立つことを願っています.

于 2011-04-12T12:23:15.960 に答える