C# 只计算一次下载';s发球
我们有以下代码可供下载:C# 只计算一次下载';s发球,c#,asp.net,download,ashx,C#,Asp.net,Download,Ashx,我们有以下代码可供下载: public class downloadRelease : IHttpHandler { public void ProcessRequest (HttpContext context) { -- snip -- context.Response.Clear(); context.Response.ContentType = "application/octet-stream"; conte
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);
它工作得很好,除了日志下载代码在下载开始时立即运行,而不是像我们预期的那样在下载完全完成时运行
有人能解释为什么会这样,以及如何更改它,使它只在完成时记录吗?我们不想计算部分下载。写入响应是一个异步过程。它由应用程序的容器管理。在您的情况下,.NET/ASP.NET运行时正在处理它。如果您想知道最后一个数据块是什么时候发送的,那么您必须在该数据块上有某种回调/事件[来自容器/运行时]。在Java中,获取此信息的应用程序服务器[Glassfish、Tomcat等]在写入文件之前,您可以尝试添加以下内容:
context.Response.BufferOutput = false;
这与您的问题完全相同,也有一个解决方案
Response.Buffer = false;
Response.TransmitFile("Tree.jpg");
Response.Close();
// logging here
这有点棘手。。。根据您希望日志记录的精确程度,它甚至可能是不可能的。。。但是
响应
对象有以下选项:
/二进制写入
/刷新
关闭
/传输文件
/刷新
关闭
BinaryWrite
和Flush
后读取文件块
第二个选项更容易实现,因为它只需调用TransmitFile
,然后调用Flush
发送完所有内容后,在登录之前,您需要调用Close
在任何情况下,在开始发送响应之前调用DisableKernelCache
都会有所帮助
注意以上所有内容都将显示出明显的性能打击!
通过为要提供服务的文件创建内存缓存,可以减少这种影响
<>关于日志记录,我会考虑将日志代码移动到<代码> EndRequest <代码>事件处理程序…
好吧,除了编写自己的基于TcpListener的HTTP服务器或攻击IIS/HTTP.SYS之外,这是最接近您目标的方法
一些参考链接:或者,使用IHttpHandler Factory的ReleaseHandler()方法,假设您将IHttpHandler标记为不可重用?非常感谢!效果很好。虽然它没有发送文件大小,所以下载还有未知的时间,但我想我可以解决这个问题。
context.Response.AddHeader(“Content-Length”,FileSize.ToString())代码>谢谢你的代码作品的魅力@汤姆古伦:我没有因此得到赏金。别担心,我正在努力,但它说我必须等,时间太早了