只有在下载完成后才计算下载次数
本文关键字:下载 计算 | 更新日期: 2023-09-27 18:09:35
我们有以下代码提供下载:
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);
它工作得很好,除了日志下载代码似乎在下载开始时就运行,而不是像我们期望的那样在下载完全完成时运行。
有人能解释一下这是为什么,以及如何改变它,使它只在完成时记录吗?我们不想计算部分下载
这篇博客的问题和你的完全一样,也有一个解决方案。
Response.Buffer = false;
Response.TransmitFile("Tree.jpg");
Response.Close();
// logging here
写响应是一个异步进程。它由应用程序的容器管理。在您的情况下,.net/asp.net运行时正在处理它。如果你想知道最后一个块是什么时候发送的,你必须有某种回调/事件[来自容器/运行时]。在Java中,获取这些信息的是应用服务器[Glassfish, Tomcat等]
您可以尝试在写入文件之前添加此内容:
context.Response.BufferOutput = false;
你试过处理HttpApplication的EndRequest事件吗?
或者,使用IHttpHandlerFactory的ReleaseHandler()方法,假设您将IHttpHandler标记为不可重用?
这有点棘手…这取决于你想要记录的精确程度,甚至可能是不可能的……但是Response
对象有以下选项:
-
BinaryWrite
/Flush
/Close
-
TransmitFile
/Flush
/Close
第一个选项要求您在每个chunk调用BinaryWrite
和Flush
之后逐个chunk读取文件…
第二个选项更容易实现,因为它只是调用TransmitFile
,然后调用Flush
。
在发送所有内容之后,在记录之前,您需要调用Close
。
在任何情况下,它可以帮助在开始发送响应之前调用DisableKernelCache
…
小心,以上所有操作将显示明显的性能冲击!可以通过为想要提供服务的文件创建内存缓存来减少这种影响。
至于日志记录,我会考虑将日志记录代码移动到EndRequest
事件处理程序…
我敢说,这是你能得到的最接近你的目标,除了编写自己的基于tcpllistener的HTTP服务器或破解IIS/HTTP。SYS .
参考链接:- http://msdn.microsoft.com/en-us/library/12s31dhy.aspx
- http://msdn.microsoft.com/en-us/library/system.web.httpresponse.binarywrite.aspx
- http://msdn.microsoft.com/en-us/library/system.web.httpresponse.flush.aspx
- http://msdn.microsoft.com/en-us/library/system.web.httpresponse.close.aspx
- http://msdn.microsoft.com/en-us/library/system.web.httpresponse.disablekernelcache.aspx
- http://msdn.microsoft.com/en-us/library/system.web.httpapplication.endrequest.aspx