我正在开发一个 .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());
}
如果不存在,它将继续从数据库中获取文件名,从磁盘读取文件,将其编码为 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
应有的情况下返回。我尝试将我的处理程序包装在 a 中try-catch
并记录异常详细信息,但它没有做任何事情 - 它只是继续将垃圾返回到请求页面。
到目前为止,我已经尝试了几件事:
- 缓冲我
image
的 4096 个块。 - 创建一个
Bitmap
对象并返回它。 - 完全删除缓存(如果我这样做,它会更频繁地失败)。
- 试图捕获异常并记录它们(它从不抛出异常)。
我在这里错过了明显的东西吗?我有点难过,有人有什么建议吗?