Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.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#HttpListener服务大文件_C#_Httplistener - Fatal编程技术网

使用C#HttpListener服务大文件

使用C#HttpListener服务大文件,c#,httplistener,C#,Httplistener,我正在尝试使用HttpListener来服务静态文件,这对小文件很有效。当文件大小变大时(使用350和600MB文件测试),服务器会因以下异常之一而阻塞: HttpListenerException:由于线程退出或应用程序请求,I/O操作已中止,或者: HttpListenerException:信号量超时时间已过期 为了消除异常并让它稳定/可靠(快速)运行,需要做哪些更改 这里有一些进一步的阐述:这基本上是一个后续问题。代码稍微扩展以显示效果。内容编写是一个循环(希望是合理的),在我的例子中,

我正在尝试使用HttpListener来服务静态文件,这对小文件很有效。当文件大小变大时(使用350和600MB文件测试),服务器会因以下异常之一而阻塞:

HttpListenerException:由于线程退出或应用程序请求,I/O操作已中止,或者:
HttpListenerException:信号量超时时间已过期

为了消除异常并让它稳定/可靠(快速)运行,需要做哪些更改

这里有一些进一步的阐述:这基本上是一个后续问题。代码稍微扩展以显示效果。内容编写是一个循环(希望是合理的),在我的例子中,块大小为64kB,但是更改值除了速度之外没有任何区别(请参阅前面提到的问题)

我尝试在浏览器和使用HttpWebRequest的C#程序中下载,这没有什么区别


根据我的研究,我认为HttpListener实际上无法将内容刷新到客户端,或者至少不能以自己的速度刷新内容。我还省略了BinaryWriter,直接向流中写入—没有区别。在基本流周围引入了一个BufferedStream-没有区别。有趣的是,如果在循环中引入了Thread.Sleep(200)或稍大一点的线程,它就可以在我的盒子上工作。然而,我怀疑它是否足够稳定,以实现真正的解决方案。给人的印象是根本没有机会让它正确运行(除了转到IIS/ASP.NET,我会求助于它,但如果可能的话,更可能远离它)。

您没有向我们展示如何初始化HttpListener的另一个关键部分。因此,我用下面的代码尝试了你的代码,它成功了

HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://*:8080/");
listener.Start();
Task.Factory.StartNew(() =>
{
    while (true)
    {
        HttpListenerContext context = listener.GetContext();
        Task.Factory.StartNew((ctx) =>
        {
            WriteFile((HttpListenerContext)ctx, @"C:\LargeFile.zip");
        }, context,TaskCreationOptions.LongRunning);
    }
},TaskCreationOptions.LongRunning);
WriteFile
是您的代码,其中
Thread.Sleep(200)已删除

如果你想看到它的完整代码



啊!我不得不承认,我陷入了一种痴迷,认为HttpListener可能会有一些问题,而不是仅仅清楚地思考。所以@L.B谢谢你让我重回正轨。基本上,我是以同样的方式实例化HttpListener的,我确实使用您的代码得到了错误。当然,我已经在我们环境中的不同PC上试用过,并看到了相同的效果,但在干净的VM机器上,您的代码和我的原始实现都可以完美地工作。我还没有找到原因,我怀疑是病毒。。。再次感谢你的帮助@L.B.:你能说明使用额外的二进制编写器有什么好处吗?与这个问题相比,这里有什么大的不同?你能总结一下问题和解决方案吗?
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://*:8080/");
listener.Start();
Task.Factory.StartNew(() =>
{
    while (true)
    {
        HttpListenerContext context = listener.GetContext();
        Task.Factory.StartNew((ctx) =>
        {
            WriteFile((HttpListenerContext)ctx, @"C:\LargeFile.zip");
        }, context,TaskCreationOptions.LongRunning);
    }
},TaskCreationOptions.LongRunning);
void WriteFile(HttpListenerContext ctx, string path)
{
    var response = ctx.Response;
    using (FileStream fs = File.OpenRead(path))
    {
        string filename = Path.GetFileName(path);
        //response is HttpListenerContext.Response...
        response.ContentLength64 = fs.Length;
        response.SendChunked = false;
        response.ContentType = System.Net.Mime.MediaTypeNames.Application.Octet;
        response.AddHeader("Content-disposition", "attachment; filename=" + filename);

        byte[] buffer = new byte[64 * 1024];
        int read;
        using (BinaryWriter bw = new BinaryWriter(response.OutputStream))
        {
            while ((read = fs.Read(buffer, 0, buffer.Length)) > 0)
            {
                bw.Write(buffer, 0, read);
                bw.Flush(); //seems to have no effect
            }

            bw.Close();
        }

        response.StatusCode = (int)HttpStatusCode.OK;
        response.StatusDescription = "OK";
        response.OutputStream.Close();
    }
}