【问题标题】:Storing image in cache将图像存储在缓存中
【发布时间】:2012-01-16 22:50:57
【问题描述】:

我有一个图像处理程序,但它总是抛出错误

我不知道我是否将图像错误地插入缓存或以错误的方式检索它。如果我尝试使用流,我会不断收到缓冲区空值。

有什么想法吗?

public void ProcessRequest(HttpContext context)
    {          
        _imageController = new ImageController();

        //Use ImageUrl to request image from external site
        string imageUrl = CastAide.AsString(context.Request["imageUrl"], String.Empty);
        //Use imageGuid and pageid to get image from user response upload
        string imageGuid = CastAide.AsString(context.Request["image"], String.Empty);
        int pageId = CastAide.AsInt32(context.Request["pageId"], -1);
        string subFolder = CastAide.AsString(context.Request["sub"], String.Empty);
        //Use ImageVaultId to return an imageVault Image
        int imageVaultId = CastAide.AsInt32(context.Request["imageVaultId"], 0);
        //Width and height determine the image size rendered
        int width = CastAide.AsInt32(context.Request["width"], 200);
        int height = CastAide.AsInt32(context.Request["height"], 200);
        bool resizeNoCrop = CastAide.AsBoolean(context.Request["resizeonly"], false);

        string cacheKey = "";
        Bitmap image = null;

    // Generate cache key
    if (!String.IsNullOrEmpty(imageGuid))            
        cacheKey = String.Format("{0}_{1}", imageGuid, "guid");                           
    else if (!String.IsNullOrEmpty(imageUrl))            
        cacheKey = String.Format("{0}_{1}", imageUrl, "url");                              
    else if (imageVaultId > 0)            
        cacheKey = String.Format("{0}_{1}", imageVaultId, "vault");                 

    // Load from cache
    if (context.Cache[cacheKey] != null)
    {           
        // Load from cache
        //MemoryStream ms = new MemoryStream((byte[])context.Cache[cacheKey]);
        //image = (Bitmap)Bitmap.FromStream(ms);
        image = context.Cache[cacheKey] as Bitmap;                             
    }
    else
    {
        if (!String.IsNullOrEmpty(imageGuid))
        {
            // load file from the local file store
            FileInfo fi;

            if (!String.IsNullOrEmpty(subFolder))
                fi = new FileInfo(_imageController.GetFilePath(subFolder, imageGuid));
            else
                fi = new FileInfo(_imageController.GetFilePath(pageId, imageGuid));

            if (fi.Exists)
                image = (Bitmap) Bitmap.FromFile(fi.FullName);
            else
                image = (Bitmap) Bitmap.FromFile(ConfigurationManager.AppSettings["ImageNotFoundPath"]);
        }
        else if (!String.IsNullOrEmpty(imageUrl))
        {
            // load file from the internet
            try
            {
                HttpWebRequest request = (HttpWebRequest) WebRequest.Create(imageUrl);
                WebResponse response = request.GetResponse();
                Stream stream = response.GetResponseStream();
                image = (Bitmap) Bitmap.FromStream(stream);
                response.Close();
            }
            catch
            {
                image = (Bitmap) Bitmap.FromFile(ConfigurationManager.AppSettings["ImageNotFoundPath"]);
            }
        }
        else if (imageVaultId > 0)
        {                   
            string filePath = ImageVaultUtility.GetSourceFileName(imageVaultId);
            FileInfo fi = new FileInfo(filePath);

            if (fi.Exists)                    
                image = (Bitmap) Bitmap.FromFile(fi.FullName);                    
            else                    
                image = (Bitmap) Bitmap.FromFile(ConfigurationManager.AppSettings["ImageNotFoundPath"]);                    
        }

        // Insert image into cache
        context.Cache.Insert(cacheKey, image, null, DateTime.Now.AddSeconds(10), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);    
        }


        if (resizeNoCrop)
            ImageUtility.ApplyResizeTransform(ref image, width, height, true);
        else
            ImageUtility.ApplyCropAndResizeTransform(ref image, width, height);

        context.Response.Clear();
        context.Response.ContentType = "image/jpeg";
        image.Save(context.Response.OutputStream, ImageFormat.Jpeg);
        image.Dispose();

    }

在检索缓存时,会发生以下情况:

【问题讨论】:

  • 你能告诉我们到底是什么错误以及代码的哪一行?
  • 您是否尝试在图像可用的 10 秒内检索图像? context.Cache.Insert(cacheKey, image, null, DateTime.Now.AddSeconds(10), ... 表示图像将在插入后 10 秒从缓存中删除。正如@comptent_tech 所提到的,我们需要有关例外情况的更好信息来进一步帮助您......
  • 进行了编辑显示问题。谢谢

标签: c# asp.net caching gdi


【解决方案1】:

如果你想在缓存中保留一个有效的图像,你不应该调用image.Dispose()。这基本上会释放非托管的 GDI+ 资源,但将图像引用保留在缓存中,GDI+ 在下次调用时会不高兴。

仅在将其从缓存中删除之前(如果您需要将其从缓存中删除)或仅在到期时执行 Dispose 调用。

【讨论】:

  • 这可能是真的,但它并没有解决上述问题。
  • @okenshield - 要进行更多调查,ArgumentException 的完整堆栈框架会有所帮助。
【解决方案2】:

您可以将此代码用于图像缓存。

http://www.codeproject.com/KB/aspnet/CachingImagesInASPNET.aspx

【讨论】:

  • 链接的文章是关于控制客户端站点上的图像缓存,而手头的问题是关于在服务器端缓存图像。
【解决方案3】:

默认情况下,当创建位图图像时,图像会保持未冻结状态,以防您的应用想要更新或修改图像。在幕后,系统还保留创建位图的线程并禁止其他线程修改图像。您收到错误是因为多个线程正在尝试访问缓存中的图像。在将其添加到缓存之前您必须做的是:

if(image.CanFreeze) {
  image.Freeze();
}

这将使文件静态且不可修改,并允许框架将图像传递给其他调用线程而不会出现问题。

要非常小心,因为如果您在没有某种管理的情况下缓存它们,那么具有许多图像文件的繁忙服务器可能会耗尽内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-02
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多