ChannelFactory: Channel Close () не закрывает соединение (netstat показывает ESTABLISHED) - PullRequest
0 голосов
/ 30 января 2020

У меня есть приложение WPF, которое обменивается данными с сервером WCF.

Я использую одну ChannelFactory для создания каналов для каждого вызова:

var channel = _channelFactory.CreateChannel();
var contextChannel = channel as ICommunicationObject;
try
  {
      channel.DoSomething();
  }
  catch (Exception)
  {
      contextChannel?.Abort();
      throw;
  }
  finally
  {
      contextChannel?.Close();
  }

Есть много запросов к серверу при запуске приложения и в некоторых точках оно останавливается, и я получаю тайм-ауты. Глядя на netstat, я вижу несколько УСТАНОВЛЕННЫХ соединений с сервером,

Когда я изменяю ServicePointManager.DefaultConnectionLimit на 10, я могу обрабатывать больше обращений к серверу, но через некоторое время он все еще останавливается с исключение тайм-аута.

Установка ServicePointManager.DefaultConnectionLimit в int.MaxValue обрабатывает все мои запросы, но у меня около 720 УСТАНОВЛЕННЫХ соединений с сервером (netstat на сервере дает мне тот же результат).

Меня смущают две вещи:

  1. Похоже, WCF не объединяет соединения, а создает новое соединение для каждого запроса
  2. Даже после закрытия канала соединение кажется, остается установленным.

Я также проверил ServicePointManager.FindServicePoint (новый Uri ("https://server: 3000 ")); и это подтверждает, что CurrentConnections находятся на пределе, которое я установил как ServicePointManager.DefaultConnectionLimit.

Я уменьшил ServicePointManager.MaxServicePointIdleTime до 500, это быстрее закрывает соединения, но все равно создает соединение для каждого звонка, который я делаю .

Как я могу убедить фабрику каналов повторно использовать существующие каналы при связи с моим сервером.

Это моя привязка:

new WebHttpBinding
{
    TransferMode = TransferMode.Streamed,
    ReceiveTimeout = TimeSpan.FromMinutes(1),
    SendTimeout = TimeSpan.FromMinutes(1),
    MaxReceivedMessageSize = 2147483647,
    MaxBufferPoolSize = 2147483647,
    ReaderQuotas =
        {
            MaxDepth = 2147483647,
            MaxStringContentLength = 2147483647,
            MaxArrayLength = 2147483647,
            MaxBytesPerRead = 2147483647,
            MaxNameTableCharCount = 2147483647
        },
    Security = new WebHttpSecurity() { Mode = WebHttpSecurityMode.Transport, Transport = new HttpTransportSecurity() { ClientCredentialType = HttpClientCredentialType.None } }
};

1 Ответ

0 голосов
/ 30 января 2020

Оказывается, что некоторые из потоков, которые возвращает сервер, не были закрыты должным образом, в результате чего клиент оставался открытым, даже после вызова Close ().

Если вызывается Close () и поток, который был возвращен клиенту, не был закрыт, соединение не будет повторно использовано, и в какой-то момент клиент получит TimeoutException.

Спасибо Чжан Лану за подсказку на форумах MSDN: https://social.msdn.microsoft.com/Forums/vstudio/en-US/a91a6d05-05ae-402e-bf7d-306289c4d0e2/wcf-with-streaming-mode-timeout-after-two-calls-when-client-and-service-are-not-on-same-machine?forum=wcf

...