我们有这个代码供下载:
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);
它工作正常,除了日志下载代码在下载开始后立即运行,而不是在下载完全按照我们的预期完成时。
有人可以解释为什么会这样,以及如何更改它以便它只在完成时记录?我们不想计算部分下载量。
答案 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
第一个选项要求您在块大小调用BinaryWrite
和Flush
后为每个块读取文件块...
第二个选项更容易实现,因为它只是调用TransmitFile
然后调用Flush
。
发送完所有内容后,您需要拨打Close
。
在任何情况下,在开始发送回复之前,可以帮助调用DisableKernelCache
...
请注意以上所有内容都会显示出明显的效果! 通过为您要提供的文件创建内存缓存可以减少此效果...
关于日志记录,我会考虑将日志记录代码移动到EndRequest
事件处理程序...
AFAIK这是你可以达到的目标,除了编写自己的基于TcpListener的HTTP服务器或黑客IIS / HTTP.SYS。
一些参考链接:
答案 4 :(得分:1)
您是否尝试过处理HttpApplication的EndRequest事件?
或许,使用IHttpHandlerFactory的ReleaseHandler()方法,假设您将IHttpHandler标记为不可重用?