【问题标题】:Exception: Unable to generate etag from dependencies异常:无法从依赖项生成 etag
【发布时间】:2013-05-28 19:52:11
【问题描述】:

我在 ASP.NET 中有一个IHttpHandler,它提供一些图像。处理程序通过以下方式设置 ETAG:

context.Response.AddFileDependency(filename);                
context.Response.Cache.SetLastModifiedFromFileDependencies();
context.Response.Cache.SetETagFromFileDependencies();
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetMaxAge(new TimeSpan(999,0,0,0));
context.Response.Cache.SetSlidingExpiration(true);
context.Response.Cache.SetValidUntilExpires(true);                
context.Response.Cache.VaryByParams["*"] = true;
byte[] buffer = File.ReadAllBytes(filename);
context.Response.ContentType = MimeMapping.GetMimeMapping(mi.Mi_filename);
context.Response.StatusCode = 200;
context.Response.BinaryWrite(buffer);

有时会在 IIS7 下得到一个 System.Web.HttpException 异常,上面写着:

无法从依赖项生成 etag。其中一个依赖项无法生成唯一 ID。

但我无法重现该问题(我知道我无法使用 ASP.NET 内部测试 Web 服务器对此进行测试)。有没有人知道为什么会发生这种情况以及我能做些什么来防止这种情况发生?

【问题讨论】:

  • 我遇到了同样的问题 - 你有没有想过这个问题?
  • 经过一番研究,我已经确定当文件依赖项是新创建的文件时会发生这种情况。我正在做与您完全相同的事情-生成图像。我生成一个新图像(写入硬盘),然后添加依赖项并告诉它从依赖项生成一个 etag。如果该文件以前存在,它可以正常工作,但如果该文件是作为当前请求的一部分生成的,我会得到System.Web.HttpException。就像依赖管理器认为该文件不存在,即使它肯定确实存在(我先检查File.Exists()

标签: c# asp.net iis-7


【解决方案1】:

我无法解释为什么会发生这种情况,但我发现让线程休眠很短的时间允许文件依赖管理器“将它放在一起”并确认在尝试从中创建 eTag 之前,确保新生成的文件确实存在。

...<code to generate "filename" goes here>...

// BUG: For some reason, even though the cache file has definitely been created at this stage, the file dependency manager
// seems to require a bit of time to "register" that the file exists before we add it to the list of dependencies.
// If we don't tell the thread to sleep, we will get an error when it generates the eTag (no idea why this happens - can't find anything on the web).
// If the cache file already existed when this request began, then there is no error.
Thread.Sleep(5);
context.Response.AddFileDependency(filename);                
context.Response.Cache.SetLastModifiedFromFileDependencies();
context.Response.Cache.SetETagFromFileDependencies();
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetMaxAge(new TimeSpan(999,0,0,0));
context.Response.Cache.SetSlidingExpiration(true);
context.Response.Cache.SetValidUntilExpires(true);                
context.Response.Cache.VaryByParams["*"] = true;
byte[] buffer = File.ReadAllBytes(filename);
context.Response.ContentType = MimeMapping.GetMimeMapping(mi.Mi_filename);
context.Response.StatusCode = 200;
context.Response.BinaryWrite(buffer);

【讨论】:

  • 是的,我也有同样的问题......把我搞砸了。我不喜欢它的工作原理(恕我直言:),因为我现在想知道 5ms 不能完全削减它的时间。至少对我来说,这与缓存的调整大小的图像服务有关,因此页面刷新可以解决所有问题。很想知道到底发生了什么
【解决方案2】:

CacheDependency.GetUniqueID() == null 时抛出异常,因此应该可以循环检查。

var i = 0;
while (++i < 10)
{
    using (var cd = new CacheDependency(fi.FullName))
       if (cd.GetUniqueID() != null) break;
    Thread.Sleep(5*i);
}
if (i == 10)
   using (var cd = new CacheDependency(fi.FullName))
      if (cd.GetUniqueID() == null)
         throw new FileLoadException("Network drive out of sync with local view of it");

【讨论】:

    猜你喜欢
    • 2018-01-29
    • 2016-10-07
    • 2014-02-21
    • 1970-01-01
    • 2012-05-07
    • 2022-08-19
    • 2014-03-26
    • 2012-11-01
    • 1970-01-01
    相关资源
    最近更新 更多