3

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

そして、これが私が得ている例外です

例外

4

1 に答える 1

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);
}
于 2012-06-07T06:24:26.257 に答える