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

Следует ли удалять ссылку WebResponse в WebException, если она связана с WebClient?

Связанный с этим вопрос: WebClient в .Net не освобождает ресурсы сокетов

При отладке проблемы утечки ресурсов я заметил, что System.Net.WebException (тип, который не является одноразовым) содержит ссылку на System.Net.WebResponse (одноразовый тип). Мне интересно, следует ли мне использовать эту ссылку при явной обработке WebResponse, как в следующем фрагменте.

using (WebClient client = new WebClient())
{
    WebException ex = Assert.Throws<WebException>(() => client.OpenRead(myUri));
    Assert.That(
        ((HttpWebResponse)ex.Response).StatusCode,
        Is.EqualTo(HttpStatusCode.ServiceUnavailable));
}

Ссылка WebException.WebResponse - это копия существующей ссылки в WebClient. Я думал, что он будет удален через WebClient.Dispose, но это не так, поскольку WebClient не переопределяет базовый метод защищенного Component.Dispose(bool). Фактически, разборка предполагает, что ресурс WebResponse никогда не удаляется, а скорее устанавливается на нуль, когда он больше не нужен.

public Stream OpenRead(Uri address)
{
    Stream stream2;

    // --- removed for brevity ---

    WebRequest request = null;
    this.ClearWebClientState();
    try
    {
        request = this.m_WebRequest = this.GetWebRequest(this.GetUri(address));
        Stream responseStream = (this.m_WebResponse = this.GetWebResponse(request)).GetResponseStream();

        // --- removed for brevity ---

        stream2 = responseStream;
    }
    catch (Exception exception)
    {

        // --- removed for brevity ---

        AbortRequest(request);
        throw exception;
    }
    finally
    {
        this.CompleteWebClientState();
    }
    return stream2;
}

... с ClearWebClientState() следующим образом:

private void ClearWebClientState()
{
    // --- removed for brevity ---

    this.m_WebResponse = null;
    this.m_WebRequest = null;
}
4b9b3361

Ответ 1

Чтобы убедиться, что ресурсы WebResponse выпущены, вы можете явно вызвать метод Close.

Здесь изменен метод ClearWebClientState:

private void ClearWebClientState()
{
    // --- removed for brevity ---
    if ( this.m_WebResponse != null )
        this.m_WebResponse.Close();
    this.m_WebResponse = null;

    this.m_WebRequest = null;
}