2012-06-07 3 views
3

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

запрос был прерван. Соединение было неожиданно закрыто

Вот мой код:

public void ProcessRequest(HttpContext context) 
{ 
    string courseKey = context.Request.QueryString["ck"]; 
    string objKey = context.Request.QueryString["file"]; 

    if(HttpRuntime.Cache[objKey] !=null) 
    { 
     using (Stream stream = (Stream)HttpRuntime.Cache[objKey]) // here is where I get an exception 
     { 
      var buffer = new byte[8000]; 
      var bytesRead = -1; 
      while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0) 
      { 
       context.Response.OutputStream.Write(buffer, 0, bytesRead); 
      } 
     } 
     return; 
    } 
    var response = Gets3Response(objKey, courseKey, context);   

    if (response != null) 
    { 
     using (response) 
     { 
      var MIMEtype = response.ContentType; 
      context.Response.ContentType = MIMEtype; 
      var cacheControl = context.Response.CacheControl; 
      HttpRuntime.Cache.Insert(objKey, response.ResponseStream, null, DateTime.UtcNow.AddMinutes(20), Cache.NoSlidingExpiration); 
      using (Stream responseStream = response.ResponseStream) 
      { 
       var buffer = new byte[8000]; 
       var bytesRead = -1; 
       while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0) 
       { 
        context.Response.OutputStream.Write(buffer, 0, bytesRead); 
       } 
      } 
     } 
    } 
} 

А вот исключение я получаю

Exception

ответ

3

Этот код является довольно запутанной. Во-первых, вы кешируете response.ResponseStream, но это было обернуто в блок using. Таким образом, к тому времени, как вы попадете в HttpRuntime.Cache.Insert, response.ResponseStream уже настроен и закрыт. Отсюда и ошибка.

Вы не должны кэшировать поток. Во-первых, если вы разместите службу распределенного кеша, ваш подход будет невозможным. Вам нужно реорганизовать это. Рассмотрим:

public class CacheAsset 
{ 
    public string FileName { get; set; } 
    public string ContentType { get; set; } 
    public byte[] Content { get; set; } 
} 

CacheAsset GetAsset(HttpContext context) 
{ 
    string courseKey = context.Request.QueryString["ck"]; 
    string objKey = context.Request.QueryString["file"]; 

    var asset = context.Cache[objKey] as CacheAsset; 

    if (asset != null) return asset; 

    using (var response = Gets3Response(objKey, courseKey, context)) 
    using (var stream = new MemoryStream()) 
    { 
     var buffer = new byte[8000]; 
     var read = 0; 

     while ((read = response.ReponseStream.Read(buffer, 0, buffer.Length)) > 0) 
     { 
     stream.Write(buffer, 0, read); 
     } 

     asset = new CacheAsset 
       { 
       FileName = objKey, 
       ContentType = reponse.ContentType, 
       Content = stream.ToArray() 
       }; 
     context.Cache.Insert(objKey, asset, null, DateTime.UtcNow.AddMinutes(20), Cache.NoSlidingExpiration); 
    } 

    return asset; 
} 

public void ProcessRequest(HttpContext context) 
{ 
    var asset = GetAsset(context); 

    context.Response.ContentType = asset.ContentType; 
    context.Response.BinaryWrite(asset.Content); 
} 
+0

У меня был HttpRuntime.Cache.Insert внутри блока использования, но я все еще получал ошибку. Я не знаю, почему я переехал за пределы используемого блока. Я думаю, что я немного расстроен. Что касается вашего второго комментария, у меня есть мои html-файлы, хранящиеся в Amazon s3, включая мои таблицы стилей изображений и файлы Javascript. Теперь мне нужно получить каждую из них отдельно. Вот как работает S3! Теперь я пытаюсь добавить поток каждого объекта в кеш, и когда я снова нажимаю ссылку, я извлекаю его из кеша, а не из Amazon S3. –

+1

Вы не можете использовать 'using' вообще, если хотите, чтобы вернуться и использовать поток из кеша. В тот момент, когда блок «use» выходит за пределы области, поток удаляется. – HackedByChinese

+0

Объекты, которые я извлекаю, - это не только изображения. они могут быть css-файлами .js файлов .html файлов или файлов, поэтому я не могу ограничить мою функцию только изображениями или растровыми изображениями по этой причине. –