2011-03-30 7 views
11

pregunta relacionada: WebClient in .Net not releasing socket resources¿Debería deshacerse de la referencia WebResponse en WebException, si se genera desde WebClient?

Al depurar un problema de pérdida de recursos, he notado que System.Net.WebException (un tipo no desechable) contiene una referencia a System.Net.WebResponse (un tipo desechable). Me pregunto si debería deshacerme de esta referencia al manejar explícitamente un WebResponse como en el siguiente fragmento.

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

La referencia WebException.WebResponse es una copia de una referencia existente en WebClient. Pensé que estaría dispuesto a través de WebClient.Dispose, pero este no es el caso, ya que WebClient no anula el método base Component.Dispose(bool) protegido. De hecho, el desmontaje sugiere que el recurso WebResponse nunca se desecha, sino que se establece en nulo cuando ya no es necesario.

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

... con ClearWebClientState() de la siguiente manera:

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

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

Respuesta

-2

para asegurarse de que los recursos de WebResponse se liberan puede llamar explícitamente el método Close.

Aquí está modificada método ClearWebClientState:

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

    this.m_WebRequest = null; 
} 
+0

Gracias por su respuesta. Me doy cuenta de que 'Close()' liberará el recurso, sin embargo, el ejemplo que di es de la implementación descompilada del tipo 'System.Web.WebClient' y no tengo el lujo de cambiar eso :) –

Cuestiones relacionadas