Нужно ли закрывать и / или удалять каналы обратного вызова, полученные через OperationContext.Current.GetCallbackChannel? - PullRequest
13 голосов
/ 17 ноября 2011

Я использую OperationContext.Current.GetCallbackChannel, чтобы получить канал для клиента, который вызвал операцию службы WCF.

Нужно ли беспокоиться о закрытии / удалении этих каналов обратного вызова или об этом позаботится фреймворк?

Ответы [ 2 ]

6 голосов
/ 22 ноября 2011

Ну, я просто попробовал это сам, и оказалось, что если вы закроете и утилизируете канал обратного вызова (после приведения к IClientChannel), весь канал службы становится бесполезным, а при вызове выдает исключение ProtocolException:

"Этот канал больше нельзя использовать для отправки сообщений, поскольку выходной сеанс был автоматически закрыт из-за выключения, инициированного сервером. Либо отключите автоматическое закрытие, установив для DispatchRuntime.AutomaticInputSessionShutdown значение false, либо рассмотрите возможность изменения протокола выключения с удаленным сервером.. "

Я предполагаю, что это нежелательное последствие или побочный эффект попытки закрыть и утилизировать канал обратного вызова, что означает, что этого не следует делать.

1 голос
/ 17 ноября 2011

По-моему, вы должны.

Механизм обратного вызова не предоставляет ничего, как протокол более высокого уровня для управления соединение между услугой и конечной точкой обратного вызова. Это зависит от разработчика придумать какой-то протокол уровня приложения или последовательный шаблон для управления Жизненный цикл соединения. Служба может перезвонить клиенту только в том случае, если канал на стороне клиента все еще открыт, что обычно достигается за счет того, что прокси-сервер не закрывается. Сохранение прокси-сервера также предотвратит сборку объекта обратного вызова. Если служба поддерживает ссылку на конечную точку обратного вызова и прокси на стороне клиента закрывается или само клиентское приложение исчезает, когда служба вызывает обратный вызов, она получает ObjectDisposedException из канала службы. Поэтому предпочтительно, чтобы клиент информировал службу, когда он больше не хочет получать обратные вызовы или когда клиентское приложение закрывается. Для этого вы можете добавить явный метод Disconnect() в контракт на обслуживание. Поскольку каждый вызов метода содержит ссылку обратного вызова, в методе Disconnect() служба может удалить ссылку обратного вызова из своего внутреннего хранилища.

вот пример:

class MyService : IServiceContract
{
   static List<IServiceContractCallback> m_Callbacks = new List<IServiceContractCallback>();
public void Connect()
{
    IServiceContractCallbackcallback = OperationContext.Current.GetCallbackChannel<IServiceContractCallback>();
    if(m_Callbacks.Contains(callback) == false)
    {
       m_Callbacks.Add(callback);
    }
}
public void Disconnect()
{
    IServiceContractCallback callback = OperationContext.Current.GetCallbackChannel<IServiceContractCallback>();
    if(m_Callbacks.Contains(callback))
    {
        m_Callbacks.Remove(callback);
    }
    else
    {
        throw new InvalidOperationException("Cannot find callback");
    }
}

Таким образом, клиент может сообщить службе, что обратный вызов больше не нужен. Это отвечает на ваш вопрос?

...