【问题标题】:Retrieving image from HTTPRuntime Cache从 HTTPRuntime 缓存中检索图像
【发布时间】:2012-06-07 05:37:14
【问题描述】:

我正在尝试从 HTTPRuntime 缓存中保存和检索图像,但出现异常。我可以将流保存到缓存,但是当我尝试检索它时,我得到一个异常消息:

请求被中止。连接意外关闭

这是我的代码:

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

这是我得到的例外

【问题讨论】:

    标签: c# asp.net asp.net-cache


    【解决方案1】:

    这段代码很混乱。首先,您正在缓存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);
    }
    

    【讨论】:

    • 我在 using 块中有 HttpRuntime.Cache.Insert 但我仍然收到错误消息。我不知道为什么我将 i 移到 using 块之外。我想只是有点沮丧。至于您的第二条评论,我将我的 html 文件存储在 Amazon s3 中,包括我的图像样式表和 Javascript 文件。现在我需要分别检索它们中的每一个。这就是 S3 的工作原理!现在我想要实现的是在缓存中添加每个对象的流,当我再次单击链接时,我从缓存而不是 Amazon S3 中检索它。
    • 如果您希望能够返回并使用缓存中的流,则根本不能使用using。 using 块超出范围的那一刻,流被释放。
    • 我检索的对象不仅仅是图像。它们可以是 css 文件、.js 文件、.html 文件或 .gif 文件,因此我不能因此将我的功能限制为图像或位图。
    • 根据要求,我无法将图像存储在磁盘上。此外,我们将在生产环境中使用 Memcached,但由于要添加和检索的 synatx 几乎相同,而且 Memcached 服务器尚未准备好,我必须使用 httpruntime.cache 来模拟 memcached。
    • 好的,下次您需要在问题中提供更多这些详细信息。在这种情况下,您可以将 response.ResponseStream 写入 MemoryStream,然后缓存字节缓冲区。这是另一个例子。
    猜你喜欢
    • 2013-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 2019-08-29
    • 2018-06-27
    • 2020-10-23
    相关资源
    最近更新 更多