我有一个运行azure worker角色,除了其他功能外,它每隔80秒左右发出一次http请求。这种情况不断发生。随着规模的扩大,它可能会发出更多的http请求,因此我编写了代码以使用begingetresponse、endgetresponse和回调。问题是…我们哪里有内存泄漏。当这个过程运行时,它会缓慢但肯定地丢失内存,直到完全耗尽为止。有时GC会启动并释放一些未使用的对象,但它会继续缓慢下降的趋势。
当执行回调并使用endGetResponse()完成请求时,我们不会接触响应流。我们需要知道的只是http状态代码,我们将其保存为自己的记录。我们从不调用getresponsestream()然后关闭它。我们确实关闭了httpwebresponse。
我的问题是:我们需要对响应流做些什么,然后关闭它吗?这样做不会导致内存泄漏吗?我所看到的所有ms示例/其他so讨论都与流有关。我想知道我们是否应该添加getresponsestream().close()…
代码如下:

// the request state class, passed along with async request
public class RequestState
{
    public HttpWebRequest Request { get; set; }
    public HttpWebResponse Response { get; set; }

    // some other properties to track which request this is..
}

...... in some other class .....

// code to perform the request
public void DoHttpRequest()
{
    HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://myurl.....");
    RequestState state = new RequestState(req); // this just sets the Request property on RequestState
    req.BeginGetResponse(OnRequestComplete, state);
}

// the callback, request has finished
public void OnRequestComplete(IAsyncResult result)
{
    RequestState state = (RequestState)result.AsyncState;
    HttpWebRequest req = state.Request;
    state.Response = (HttpWebResponse)req.EndGetResponse(result);

    // we do not care about the body of the response
    // all we want is the status code, which we store somewhere else..

    if (state.Response.StatusCode == HttpStatusCode.OK || state.Response.StatusCode == HttpStatusCode.Created)
    {
         // comm was successful
         // save this result code somewhere...
    }
    else if (state.Response.StatusCode == HttpStatusCode.RequestTimeout || state.Response.StatusCode == HttpStatusCode.GatewayTimeout)
    {
          // comm timed out
          // save this result code somewhere..
    }
    else
    {
          // something else, comm failed
          // save this result code somewhere..
    }

    // we've got the relevant data from the HttpWebResponse object, dispose of it
    state.Response.Close();
}

谢谢您!

最佳答案

我签入了reflector(.net 4.0最新版本,由azure应用程序使用):HttpWebResponse.Close确实关闭了将由GetResponseStream返回的流。
听起来其他地方有问题。
简而言之,关闭流还应该调用原始流上的Abort,但逻辑相当复杂。您可能想尝试显式调用HttpWebRequest,看看是否清除了内存使用。

10-07 19:01
查看更多