WebClient в .Net не освобождает ресурсы сокета - PullRequest
4 голосов
/ 01 ноября 2010

У меня проблемы с некоторым простым тестовым кодом, который выполняет массовую загрузку с одного из наших остальных сервисов. Похоже, что сокет низкого уровня не освобождается вызовом Dispose. Вот основной код;

foreach(...)
{
  using(WebClient client = new WebClient())
  {
    string results = client.DownloadString("http://host/request");
    client.Dispose();
  }
}

Это вызывает исключение после 255 циклов. Я попытался добавить эту строку (с помощью некоторых предложений из другого сообщения stackoverflow).

System.Net.ServicePointManager.DefaultConnectionLimit = 500;

Тогда я получаю исключение после 500 циклов. Поэтому, мне кажется, низкоуровневое сокетное соединение не освобождается.

Кто-нибудь еще видел эту проблему? Знаете ли вы работу вокруг.

Спасибо

Ответы [ 3 ]

0 голосов
/ 01 ноября 2010

Вы можете попробовать использовать HttpWebRequest вместо WebClient.По моему опыту, мне обычно легче делать то, что я хочу с этим API, хотя использовать его не так просто.Я полагаю, что вы можете намного легче контролировать соединения с HttpWebRequest.

0 голосов
/ 01 ноября 2010

WebClient не переопределяет Dispose, которое он наследует от Component.

Не должно быть необходимости вызывать Dispose, и я не получаю ошибку, о которой вы упоминали.Пожалуйста, упомяните другой пост stackoverflow.

На самом деле, WebClient не сохраняет состояния, которое потребовало бы dsiposing и довольно без состояния.Глядя на реализацию в Reflector, становится очевидным, что он ищет ресурсы здесь (метод DownloadDataInternal вызывается из DownloadString):

private byte[] DownloadDataInternal(Uri address, out WebRequest request)
{
    byte[] buffer2;
    if (Logging.On)
    {
        Logging.Enter(Logging.Web, this, "DownloadData", address);
    }
    request = null;
    try
    {
        request = this.m_WebRequest = this.GetWebRequest(this.GetUri(address));
        buffer2 = this.DownloadBits(request, null, null, null);
    }
    catch (Exception exception)
    {
        if (((exception is ThreadAbortException) || (exception is StackOverflowException)) || (exception is OutOfMemoryException))
        {
            throw;
        }
        if (!(exception is WebException) && !(exception is SecurityException))
        {
            exception = new WebException(SR.GetString("net_webclient"), exception);
        }
        AbortRequest(request);
        throw exception;
    }
    catch
    {
        Exception exception2 = new WebException(SR.GetString("net_webclient"), new Exception(SR.GetString("net_nonClsCompliantException")));
        AbortRequest(request);
        throw exception2;
    }
    return buffer2;
}
0 голосов
/ 01 ноября 2010

Вы можете попробовать вызвать GC.Collect, чтобы заставить GC работать, кажется, это может быть проблема с вашим

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