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

Ste*_*idi 11 .net dispose webclient httpwebrequest httpwebresponse

相关问题:.Net中的WebClient没有释放套接字资源

在调试资源泄漏问题时,我注意到System.Net.WebException(非一次性类型)包含对System.Net.WebResponse(一次性类型)的引用.我想知道在显式处理WebResponse以下代码段中的as 时是否应该处理此引用.

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

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;
}
Run Code Online (Sandbox Code Playgroud)

...... ClearWebClientState()如下:

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

    this.m_WebResponse = null;
    this.m_WebRequest = null;
}
Run Code Online (Sandbox Code Playgroud)

Vad*_*iak -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;
}
Run Code Online (Sandbox Code Playgroud)