【问题标题】:Should one dispose of the WebResponse reference in WebException, if raised from WebClient?如果从 WebClient 提出,是否应该在 WebException 中处理 WebResponse 引用?
【发布时间】:2011-07-26 06:52:58
【问题描述】:

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

在调试资源泄漏问题时,我注意到System.Net.WebException(非一次性类型)包含对System.Net.WebResponse(一次性类型)的引用。我想知道在显式处理 WebResponse 时是否应该处理此引用,如下面的 sn-p 所示。

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

【问题讨论】:

    标签: .net httpwebrequest webclient dispose httpwebresponse


    【解决方案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;
    }
    

    【讨论】:

    • 感谢您的回复。我意识到Close() 将释放资源,但是我给出的示例来自System.Web.WebClient 类型的反编译实现,我没有改变它的奢侈:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-01
    相关资源
    最近更新 更多