5

IHttpHandler在 ASP.NET 中有一个提供一些图像的服务。处理程序通过以下方式设置 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);

System.Web.HttpException有时会在 IIS7 下得到一个异常,它说:

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

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

4

2 回答 2

7

我无法解释为什么会发生这种情况,但我发现让线程休眠很短的时间允许文件依赖管理器“将它放在一起”并在尝试之前确认新生成的文件确实存在从中创建一个 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);
于 2014-01-13T13:12:09.650 回答
0

当 时抛出异常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");
于 2017-05-12T09:21:37.107 回答