只有在下载后才计算下载

时间:2011-09-23 19:57:22

标签: c# asp.net download ashx

我们有这个代码供下载:

public class downloadRelease : IHttpHandler {

    public void ProcessRequest (HttpContext context) {

        -- snip --

        context.Response.Clear();
        context.Response.ContentType = "application/octet-stream";
        context.Response.AddHeader("Content-Disposition", "attachment; filename=" + OriginalFileName);
        context.Response.WriteFile(Settings.ReleaseFileLocation + ActualFileName);

        // Log download
        Constructor.VersionReleaseDownload.NewReleaseDownload(ActualFileName);

它工作正常,除了日志下载代码在下载开始后立即运行,而不是在下载完全按照我们的预期完成时。

有人可以解释为什么会这样,以及如何更改它以便它只在完成时记录?我们不想计算部分下载量。

5 个答案:

答案 0 :(得分:5)

blog post与您的问题完全相同,也是解决方案。

Response.Buffer = false;
Response.TransmitFile("Tree.jpg");
Response.Close();
// logging here

答案 1 :(得分:4)

写响应是一个异步过程。它由应用程序的容器管理。在您的情况下,.NET / ASP.net运行时正在处理它。如果你想知道最后一个块发送的时间,你必须要有某种回调/事件[来自容器/运行时]。在Java中,它是获取此信息的应用程序服务器[Glassfish,Tomcat等]

答案 2 :(得分:1)

您可以在编写文件之前尝试添加它:

context.Response.BufferOutput = false;

答案 3 :(得分:1)

这有点棘手......取决于您希望日志记录的准确程度,甚至可能是不可能......但Response对象有以下选项:

  • BinaryWrite / Flush / Close

  • TransmitFile / Flush / Close

第一个选项要求您在块大小调用BinaryWriteFlush后为每个块读取文件块...

第二个选项更容易实现,因为它只是调用TransmitFile然后调用Flush

发送完所有内容后,您需要拨打Close

在任何情况下,在开始发送回复之前,可以帮助调用DisableKernelCache ...

请注意以上所有内容都会显示出明显的效果! 通过为您要提供的文件创建内存缓存可以减少此效果...

关于日志记录,我会考虑将日志记录代码移动到EndRequest事件处理程序...

AFAIK这是你可以达到的目标,除了编写自己的基于TcpListener的HTTP服务器或黑客IIS / HTTP.SYS。

一些参考链接:

答案 4 :(得分:1)

您是否尝试过处理HttpApplication的EndRequest事件?

或许,使用IHttpHandlerFactory的ReleaseHandler()方法,假设您将IHttpHandler标记为不可重用?