0

指定された 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て例外の詳細を記録しようとしましたが、何もしません。要求元のページにゴミを返し続けるだけです。

画像ハンドラーの問題

これまでのところ、私はいくつかのことを試しました:

  1. imageの 4096 チャンクをバッファリングします。
  2. オブジェクトを作成し、Bitmapこれを返します。
  3. キャッシュを完全に削除します (これを行うと、失敗する頻度がわずかに高くなります)。
  4. 例外をキャプチャして記録しようとしています (例外はスローされません)。

ここで明らかなことを見逃していますか?? 私は少し困惑しています、誰かアドバイスはありますか?

4

2 に答える 2