Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 只计算一次下载';s发球_C#_Asp.net_Download_Ashx - Fatal编程技术网

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之外,这是最接近您目标的方法

一些参考链接:


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


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

非常感谢!效果很好。虽然它没有发送文件大小,所以下载还有未知的时间,但我想我可以解决这个问题。
context.Response.AddHeader(“Content-Length”,FileSize.ToString())谢谢你的代码作品的魅力@汤姆古伦:我没有因此得到赏金。别担心,我正在努力,但它说我必须等,时间太早了