【问题标题】:Response.End() vs HttpContext.Current.ApplicationInstance.CompleteRequest() [duplicate]Response.End() 与 HttpContext.Current.ApplicationInstance.CompleteRequest() [重复]
【发布时间】:2012-05-23 03:08:48
【问题描述】:

我们应用程序的用户在一天中至少每两秒钟下载一次附件。

上一个场景:

在用户下载附件后,我们使用 Response.End() 中止与客户端的连接。当我们遇到性能问题时,我们开始记录异常,其中最重复的一个是线程中止异常。由于我们从 Web 服务获取附件,因此我们必须进行一些清理,并且我们在 try-catch-finally 块中进行了清理。经过一番研究,我了解到 Response.End() 之后的任何代码即使在 finally 块中也不会被执行。对吗?

当前情景:

我已经阅读了堆栈溢出中关于 Response.End() 有害的线程,并且仅在真正需要时才需要使用它,因此我决定改用 HttpContext....CompleteRequest() 。使用此代码,完成了所需的清理工作,但呈现的 html 被附加到下载的附件中。我尝试覆盖同一篇文章中建议的 Render 和 RaisePostBackEvent,但问题仍然存在。有关如何解决此问题的任何想法都会有所帮助。

代码:

HttpContext.Current.Response.Clear();

Response.ClearContent();

Response.ClearHeaders();

Response.AddHeader("Content-Disposition", "attachment; filename=" +   
filename);
Response.AddHeader("Content-Length", fileContent.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.BinaryWrite(fileContent);
Response.Flush();

【问题讨论】:

  • 请不要在标题前加上“C#”之类的前缀。这就是标签的用途。
  • 当然。对于那个很抱歉。我刚开始在这里发帖。我会确保不再重复。

标签: c#


【解决方案1】:

旧 Q,不确定它是否有帮助,但在创建 PDF 文件以传递给浏览器时,我的做法与您的示例基本相同。但是,在处理结束时,我有以下内容:

    Response.OutputStream.Flush()
    Response.OutputStream.Close()
    Response.End()

.Close() 的添加基本上。似乎在生产中运行良好。

Ed:我也发现了这个,提到 Close():Is Response.End() considered harmful?

解决您的问题的另一种方法是简单地覆盖 Page_PreRender() 并将内容交付代码放在那里(这在功能上是有意义的)。那么你肯定不会得到任何不需要的 HTML,而且根本不需要 Response.End()。

【讨论】:

    【解决方案2】:

    Response.End 在内部抛出 ThreadAbortException 以终止请求 - 如果您需要进行某种清理,这需要在调用 Response.End 之前完成

    Response.RedirectResponse.End 不能很好地与 try / catch 块交互。因此,在您的情况下,您应该在 try / catch 中将所有逻辑写入响应流,然后在 finally 块之后简单地调用 Response.End

    【讨论】:

    • 感谢您的回复。我知道这会起作用,但是我怎样才能摆脱 ThreadAbortException,它会填满我的日志文件,并且可能还会占用服务器上的一些内存。有没有办法在没有 Response.End() 的情况下做到这一点。编辑:另外,如果我在 finally 块之后使用 Response.End() ,我会遇到相同的问题,即渲染的 html 被附加到下载的文档中。反正我可以解决。再次感谢您的回复。
    • 停止将Response.End 包裹在您的try/catch 中。 Response.End 使用 ThreadAbortException 结束响应。这就是它的工作原理。你基本上捕捉到了框架的异常。
    • 好的。我不会将 Response.End() 包装在 try.. 中。感谢您指出了这一点。你能回复我的编辑吗,我刚刚尝试了你建议的代码,我又遇到了 html 问题。我非常感谢您的回复。谢谢。
    • 我已经用代码编辑了帖子,这是 try..catch 块中的代码,我在 finally 之后放置了 response.end()。此外,如果有帮助,我将重定向到一个空的下载页面,上面发布的代码位于该下载页面的 Page_load 中,它将显示打开/保存对话框。谢谢。
    • finally 块在任何情况下都会被执行。他们永远不会被跳过。没有办法杀死线程。
    猜你喜欢
    • 2012-09-13
    • 2013-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多