从缓存中获取位图
每当我尝试获取从上下文缓存的位图时,我都会收到参数异常。位图是从缓存的对象中转换而来的,但其内容已损坏。
异常在
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.
}
}
}
任何帮助将不胜感激。
Whenever I try to get a bitmap I have cached from the context I am getting an argument exception. The bitmap is cast from the cached object but it's contents are corrupted.
The exception is thrown on the line
ImageFormat imageFormat = bitmap.RawFormat;
bitmap.RawFormat' threw an exception of type 'System.ArgumentException'
Which just gives me the message 'Parameter not valid.'
When I stick a breakpoint in the code look at the bitmap created from the cache all the properties report back the same exception.
Here's the process request from my handler....
/// <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.
}
}
}
Any help would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我建议不要持有资源超过其需要的时间。
至于上面的代码,问题在于,当您获取保存的图像时,您并没有创建新的位图 - 您正在从缓存中检索现有的位图,该位图可能已经被处理掉了。尝试使用以下内容代替:
I can recommend not holding onto resources for longer than they're needed.
As for the code above, the issue is that you aren't creating a new bitmap when you get a saved image - you're retrieving an existing one from the cache, which has probably already been disposed of. Try using the following instead:
当您缓存图像对象时,您将在 using 块内执行此操作:
在此 using 块的末尾,您的位图将被释放。因此您不能再次使用它。如果您想再次使用缓存中的位图,则需要停止处理该位图。
然而,考虑到您只想再次返回相同的图像(如果已缓存),则仅缓存 MemoryStream 可能会更简单、更高效 - 这不会受到任何不可见的 GDI+ 关系,并且可以在几乎不进行缓存处理的情况下返回打。
When you cache the image object you are doing so inside a using block:
At the end of this using block, your bitmap will be disposed. Therefore you can't use it again. You need to stop disposing the bitmap if you want to use it again from the cache.
However, given that you just want to return the same image again if it's cached, it might be simpler and more efficient to just cache the MemoryStream - this doesn't suffer any invisible GDI+ ties and can be returned with almost no processing on a cache hit.