每当我尝试获取一个位图时,我从上下文中缓存,我得到一个参数异常。位图是从缓存的对象转换而来的,但它的内容已损坏。
行抛出异常
ImageFormat imageFormat = bitmap.RawFormat;
bitmap.RawFormat'引发了类型'System.ArgumentException'的异常
这只是给我提供了'参数无效'的信息。
当我在代码中粘贴断点时,查看从缓存创建的位图,所有属性都会报告相同的异常。
这是来自我的处理程序的处理请求....
/// <summary>
/// Processes the image request.
/// </summary>
/// <param name="context">The httpContext handling the request.</param>
public void ProcessRequest(HttpContext context)
{
//write your handler implementation here.
if (!string.IsNullOrEmpty(context.Request.QueryString["file"]))
{
string file = context.Request.QueryString["file"];
bool thumbnail = Convert.ToBoolean(context.Request.QueryString["thumb"]);
// Throw in some code to check width and height.
int width = Convert.ToInt32(context.Request.QueryString["width"]);
int height = Convert.ToInt32(context.Request.QueryString["height"]);
// Store our context key.
string key = file;
// Strip away our cache data value.
file = file.Substring(0, file.LastIndexOf("_", StringComparison.OrdinalIgnoreCase));
OnServing(file);
try
{
//Check the cache for a file.
Bitmap bitmap = (Bitmap)context.Cache[key];
if (bitmap != null)
{
ImageFormat imageFormat = bitmap.RawFormat;
// We've found something so lets serve that.
using (MemoryStream ms = new MemoryStream())
{
bitmap.Save(ms, imageFormat);
context.Response.BinaryWrite(ms.ToArray());
}
}
else
{
// Nothing found lets create a file.
// Lock the file to prevent access errors.
lock (this.syncRoot)
{
string path = HostingEnvironment.MapPath(String.Format("~/Images/{0}", file));
FileInfo fi = new FileInfo(path);
if (fi.Exists)
{
using (Bitmap img = (Bitmap)Bitmap.FromFile(path))
{
ImageFormat imageFormat = img.RawFormat;
if (thumbnail)
{
ImageEditor imageEditor = new ImageEditor(img);
Size size = new Size(width, height);
imageEditor.Resize(size, true);
imageEditor.FixGifColors();
using (MemoryStream ms = new MemoryStream())
{
imageEditor.Image.Save(ms, imageFormat);
// Add the file to the cache.
context.Cache.Insert(key, img, new System.Web.Caching.CacheDependency(path));
imageEditor.Dispose();
context.Response.BinaryWrite(ms.ToArray());
}
}
else
{
using (MemoryStream ms = new MemoryStream())
{
img.Save(ms, imageFormat);
// Add the file to the cache.
context.Cache.Insert(key, img, new System.Web.Caching.CacheDependency(path));
context.Response.BinaryWrite(ms.ToArray());
}
}
OnServed(file);
}
}
else
{
OnBadRequest(file);
}
}
}
}
catch (Exception ex)
{
throw ex;
// OnBadRequest(ex.Message);
// return a default empty file here.
}
}
}
非常感谢任何帮助。
答案 0 :(得分:3)
我建议不要长时间保留资源。
至于上面的代码,问题是当你得到一个保存的图像时你没有创建一个新的位图 - 你正在从缓存中检索一个现有的位图,这可能已经被处理掉了。请尝试使用以下内容:
// When saving to the cache, use a MemoryStream to save off the bitmap as an array of bytes
using (MemoryStream ms = new MemoryStream()) {
bitmap.Save(ms, bitmap.RawFormat);
context.Cache.Insert(key, (byte[])ms.ToArray(), ...
...
}
...
// When retrieving, create a new Bitmap based on the bytes retrieved from the cached array
if (context.Cache[key] != null) {
using (MemoryStream ms = new MemoryStream((byte[])context.Cache[key])) {
using (Bitmap bmp = new Bitmap(ms)) {
bmp.Save(context.Response.OutputStream ...
...
答案 1 :(得分:2)
当您在使用块内缓存图像对象时:
using (Bitmap img = (Bitmap)Bitmap.FromFile(path))
{
// ... lots of code
// Add the file to the cache.
context.Cache.Insert(key, img, new System.Web.Caching.CacheDependency(path));
// ... other code
}
在此使用块的末尾,您的位图将被丢弃。因此,您无法再次使用它。如果要从缓存中再次使用位图,则需要停止处理位图。
但是,考虑到你只是想在缓存时再次返回相同的图像,只是缓存MemoryStream可能更简单,更有效 - 这不会遭受任何不可见的GDI +关系,并且几乎不需要处理就可以返回在缓存命中。