WCF Duplex: как обработать выброшенное исключение в дуплексном обратном вызове - PullRequest
2 голосов
/ 07 апреля 2011

Как мне обработать исключение, сгенерированное в методе обратного вызова на клиенте в настройке дуплекса 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");
    }
}

1 Ответ

1 голос
/ 12 апреля 2011

Как выяснилось, вы не можете ожидать, что событие Faults будет вызвано.Таким образом, лучший способ восстановить соединение - это сделать, когда последующий вызов 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...]
    //*/
}

Очевидно,В моем примере кода Исключение будет снова выдано, но я надеюсь, что это полезно, чтобы дать людям представление о том, как восстановить соединение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...