是否应该在WebException中处理WebResponse引用,如果从WebClient引发?

时间:2011-03-30 17:38:02

标签: .net httpwebrequest webclient dispose httpwebresponse

相关问题:WebClient in .Net not releasing socket resources

在调试资源泄漏问题时,我注意到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资源从未被处理掉,而是在不再需要时设置为null。

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;
}

1 个答案:

答案 0 :(得分:-2)

为了确保释放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;
}