首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >必须显式关闭异步http请求的ResponseStream吗?

必须显式关闭异步http请求的ResponseStream吗?
EN

Stack Overflow用户
提问于 2011-08-22 17:35:10
回答 4查看 1.3K关注 0票数 2

我有一个Azure工作者角色,在其他函数中,它每80秒左右发出一些HTTP请求。这种情况时有发生。随着我们的扩展,它可能会产生更多的HTTP请求,所以我编写了使用BeginGetResponse、EndGetResponse和回调的代码。问题是..。我们在某个地方有记忆泄露。当这个过程运行时,它会缓慢但肯定地失去记忆,直到完全耗尽。有时GC会启动并释放一些未使用的对象,但是它继续其缓慢的下降趋势。

当我们的回调执行并且用EndGetResponse()完成请求时,我们不会触及响应流。我们所需要知道的就是HTTP状态代码,我们将其保存在自己的记录中。我们从不调用GetResponseStream()并随后关闭它。我们确实关闭了() HttpWebResponse。

我的问题是:我们需要对Response做些什么,然后关闭它吗?这样做不会导致内存泄漏吗?所有MS示例/其他,所以我看到的讨论对流做了一些事情。我想知道我们是否应该添加GetResponseStream().Close().

下面是代码:

代码语言:javascript
运行
复制
// 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();
}

谢谢!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-08-22 18:18:27

我签入了Reflector ( Azure应用程序使用的.NET 4.0最新版本):HttpWebResponse.Close确实关闭了GetResponseStream返回的流。

听起来好像其他地方出了什么问题。

简单地看,关闭流也应该在原始的Abort上调用HttpWebRequest,但是逻辑非常复杂。您可能需要尝试显式调用Abort并查看内存使用是否已清除。

票数 1
EN

Stack Overflow用户

发布于 2011-08-22 17:44:09

您可以使用using语句来使用响应,确保它被释放了!如果你不打算再读一遍流的内容,我看不出有什么坏处!再想一想:在回调中,您确定在尝试记录结果时没有异常吗?

票数 0
EN

Stack Overflow用户

发布于 2011-08-22 21:34:57

我遇到了一个和你非常相似的问题。我有一些员工角色,它们会周期性地进入Azure无法再与其通信的状态,并且它们不会像我预期的那样重新启动,当Azure实例上发生错误时,它们会重新启动。

在与MS support的人进行了友好的交谈之后,结果发现我们的实例正在耗尽内存。当这种情况发生时,app控制器服务(它会在VM和VM之外的Azure管理工具之间进行所有的交谈)崩溃,这意味着您不能对管理门户中的实例做任何事情。

结果发现,我们有一个非常经常使用的对象,当我们完成任务时,我们并没有调用dispose。

因此,在回答您的问题时,作为一个一般原则,如果一个对象有一个dispose方法,那么当您完成处理它时,您应该调用dispose。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7151237

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档