指定された ID に基づいて画像を返すために、.NET HTTP ハンドラー (IsReusable を true に設定) に取り組んでいます。渡される URL は次のようになりますReadImage.ashx?id=N
。ハンドルがリクエストを受け取ると、ID を取得し、次のように、以前に base64 でエンコードされたイメージを HTTP キャッシュで検索します。
byte[] image;
if (context.Cache["image_" + id] != null)
{
image = Convert.FromBase64String(context.Cache["image_" + id].ToString());
}
そこにない場合は、データベースからファイル名を取得し、ディスクからファイルを読み取り、base64 にエンコードしてバイトを保存しimage
、最後に次のように 20 分間画像をキャッシュします。
else
{
var dbImage = m_database.Images.Single(i => i.Id.Equals(id));
string filePath = context.Server.MapPath(string.Format("~/{base path}/{0}", dbImage.Filename));
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
image = new byte[fs.Length];
fs.Read(image, 0, image.Length);
context.Cache.Add("image_" + dbImage.Id, Convert.ToBase64String(image), null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(20), CacheItemPriority.Normal, null);
}
}
次に、現在のコンテキストの出力ストリームへのバッファを最終的BinaryWrite
に作成します。image
context.Response.ContentType = "image/png";
context.Response.BinaryWrite(image);
context.Response.Flush();
現在、これはすべて完全に正常に機能していますが、常にではありません。ときどき壊れた画像が表示されますが、更新すると (99% の確率で) 画像が表示されます。
Chrome のデバッガーでネットワーク トラフィックを見るとtext/html
、画像が壊れていて本来の状態ではない場合に、ハンドラーが返されていることがわかりimage/png
ます。ハンドラーを でラップしtry-catch
て例外の詳細を記録しようとしましたが、何もしません。要求元のページにゴミを返し続けるだけです。
これまでのところ、私はいくつかのことを試しました:
- 私
image
の 4096 チャンクをバッファリングします。 - オブジェクトを作成し、
Bitmap
これを返します。 - キャッシュを完全に削除します (これを行うと、失敗する頻度がわずかに高くなります)。
- 例外をキャプチャして記録しようとしています (例外はスローされません)。
ここで明らかなことを見逃していますか?? 私は少し困惑しています、誰かアドバイスはありますか?