Хранение изображения в кеше - PullRequest
2 голосов
/ 09 декабря 2011

У меня есть обработчик изображения, но он продолжает выдавать ошибки

Я не знаю, неправильно ли я вставляю изображение в кеш или получаю его неправильно. Я продолжаю получать нулевой буфер, если я пытаюсь использовать поток.

есть идеи?

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();

    }

при извлечении кеша происходит следующее:

enter image description here

Ответы [ 3 ]

2 голосов
/ 09 декабря 2011

Если вы хотите сохранить действительное изображение в кэше, вам не следует делать вызов image.Dispose().Это в основном высвободит неуправляемые ресурсы GDI +, но сохранит ссылку на изображение в кеше, и GDI + не будет удовлетворен при следующем вызове.

Делайте вызов Dispose только до удаления его из кэша (если вынеобходимо удалить его из кэша) или только по истечении срока действия.

0 голосов
/ 13 апреля 2013

По умолчанию при создании растрового изображения изображение остается незамерзшим, если ваше приложение хочет обновить или изменить изображение.Под прикрытиями система также сохраняет, какой поток создал растровое изображение, и запрещает другим потокам изменять изображение.Вы получаете ошибку, потому что несколько потоков пытаются получить доступ к изображению в кеше.Перед добавлением его в кеш нужно сделать следующее:

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

, что сделает файл статичным и неизменяемым, и позволит инфраструктуре без проблем передавать образ другим вызывающим потокам.

Будьте очень осторожны, поскольку на занятом сервере с большим количеством файлов изображений может не хватить памяти, если вы кешируете их без какого-либо управления.

0 голосов
/ 09 декабря 2011

вы можете использовать этот код для кэширования изображений.

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

...