C# HTTP映像处理程序有时无法返回映像

C# HTTP映像处理程序有时无法返回映像,c#,httphandler,C#,Httphandler,我正在使用.NET HTTP处理程序(IsReusable设置为true)根据指定的ID返回一个图像。传递的URL看起来像这样ReadImage.ashx?ID=N。一旦句柄接收到请求,它将获取ID并在HTTP缓存中查找以前的base64编码图像,如下所示: byte[] image; if (context.Cache["image_" + id] != null) { image = Convert.FromBase64String(context.Cache["image_" +

我正在使用.NET HTTP处理程序(IsReusable设置为true)根据指定的ID返回一个图像。传递的URL看起来像这样
ReadImage.ashx?ID=N
。一旦句柄接收到请求,它将获取ID并在HTTP缓存中查找以前的base64编码图像,如下所示:

byte[] image;
if (context.Cache["image_" + id] != null)
{
    image = Convert.FromBase64String(context.Cache["image_" + id].ToString());
}
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);
    }
}
如果不存在,则继续从数据库获取文件名,从磁盘读取文件,将其编码为base64,并将字节存储在
image
中,最后将图像缓存20分钟,如下所示:

byte[] image;
if (context.Cache["image_" + id] != null)
{
    image = Convert.FromBase64String(context.Cache["image_" + id].ToString());
}
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
my
image
缓冲区写入当前上下文的输出流:

context.Response.ContentType = "image/png";
context.Response.BinaryWrite(image);
context.Response.Flush();
现在,这一切都运行得很好——但并非一直如此。我偶尔会得到一个损坏的图像,但刷新后图像(99%的时间)就在那里了

查看Chrome调试器中的网络流量,我可以看到我的处理程序在图像被破坏的情况下返回
text/html
,而不是应该返回的
image/png
。我曾尝试将我的处理程序包装在一个
try catch
中,并记录异常详细信息,但它没有做任何事情——它只是继续将垃圾返回到请求页面

到目前为止,我已经尝试了一些方法:

  • 将我的
    图像
    缓冲成4096个块
  • 创建
    位图
    对象并返回该对象
  • 完全删除缓存(如果这样做,失败的频率会稍微高一些)
  • 尝试捕获异常并记录它们(它从不抛出异常)

  • 我是不是错过了这里显而易见的东西??我有点困惑,有人有什么建议吗?

    我猜。我的问题在于以下代码:

    if (context.Cache["image_" + id] != null)
    {
        image = Convert.FromBase64String(context.Cache["image_" + id].ToString());
    }
    
    缓存可能随时失效。很可能在if语句的计算结果为true后,缓存项立即变为无效,最终第二个get将变为null。最好这样做(不是100%确定):


    与其说是一个解决方案,不如说是一个更好的解决办法

    我决定为它创建一个MVC操作,而不是使用通用处理程序。这里是行动,我没有一次失败,它似乎要快得多

    [HttpGet]
    public ActionResult GetImage(int id)
    {
        byte[] buffer;
        if (HttpContext.Cache["image_" + id] == null)
        {
            var dbMediaItem = m_database.MediaItems.Single(i => i.Id.Equals(id));
            string path = string.Format(Server.MapPath("~/{base path}/{0}"), dbMediaItem.Filename);
            using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                buffer = new byte[fs.Length];
                fs.Read(buffer, 0, buffer.Length);
                HttpContext.Cache.Add("image_" + id, Convert.ToBase64String(buffer), null, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(20), CacheItemPriority.Normal, null);
            }
        }
        else
        {
            buffer = Convert.FromBase64String(HttpContext.Cache["image_" + id].ToString());
        }
        return base.File(buffer, "image/png");
    }
    

    不幸的是,如果我完全删除缓存,这个问题仍然存在(尽管稍微更糟),不过还是要感谢大家的提醒。