HttpListener を使用して静的ファイルを提供しようとしていますが、これは小さなファイルでうまく機能します。ファイル サイズが大きくなると (350 MB と 600 MB のファイルでテスト)、サーバーは次のいずれかの例外で
停止します。セマフォのタイムアウト期間が過ぎました。
例外を取り除き、安定して信頼できる (そして高速に) 実行するには、何を変更する必要がありますか?
さらに詳しく説明します。これは基本的に、この以前の質問に対するフォローアップの質問です。コードは、効果を示すために少し拡張されています。コンテンツの書き込みは (できれば妥当な) チャンク サイズ (私の場合は 64kB) でループしていますが、値を変更しても速度以外に違いはありませんでした (言及された古い質問を参照)。
using( FileStream fs = File.OpenRead( @"C:\test\largefile.exe" ) ) {
//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=largefile.EXE" );
byte[] buffer = new byte[ 64 * 1024 ];
int read;
using( BinaryWriter bw = new BinaryWriter( response.OutputStream ) ) {
while( ( read = fs.Read( buffer, 0, buffer.Length ) ) > 0 ) {
Thread.Sleep( 200 ); //take this out and it will not run
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();
}
ブラウザーでダウンロードを試みていますが、HttpWebRequest を使用して C# プログラムでもダウンロードを試みていますが、違いはありません。
私の調査によると、HttpListener は実際にはコンテンツをクライアントにフラッシュできないか、少なくとも独自のペースでフラッシュできると思います。また、BinaryWriter を省略して、ストリームに直接書き込みましたが、違いはありません。基本ストリームの周りに BufferedStream を導入しました - 違いはありません。面白いことに、ループに Thread.Sleep(200) またはそれより少し大きい値を導入すると、私のボックスで動作します。ただし、実際のソリューションとして十分に安定しているとは思えません。この質問は、それを正しく実行する機会がまったくないという印象を与えます (私が頼る IIS/ASP.NET に移行する以外に、可能であれば近づかない可能性が高いです)。