Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Механизм обратного вызова не предоставляет ничего, как протокол более высокого уровня для управления соединение между службой и конечной точкой обратного вызова. Это зависит от разработчика придумать какой-либо протокол на уровне приложения или согласованный шаблон для управления жизненный цикл соединения. Служба может только перезвонить клиенту, если канал на стороне клиента все еще открыт, что обычно достигается, не закрывая прокси. Сохранение открытого прокси также предотвратит сбор объекта обратного вызова. Если служба поддерживает ссылку на конечную точку обратного вызова, а прокси-сервер на стороне клиента закрыт или сам клиентское приложение ушло, когда служба вызывает обратный вызов, он получит 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");
    }
}

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