gpt4 book ai didi

.net - WinInet 如何确定缓存什么以及何时缓存?

转载 作者:可可西里 更新时间:2023-11-01 15:12:21 24 4
gpt4 key购买 nike

我正在试验我的 .NET 客户端和服务器之间的缓存。在 WinInet 决定缓存结果之前,我看到一个看似随机的端点命中数。

.NET 客户端使用 HttpWebRequest 发出请求:

HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uiTextBoxUrl.Text);
var policy = new RequestCachePolicy(RequestCacheLevel.CacheIfAvailable);
webRequest.CachePolicy = policy;
WebResponse webResponse = webRequest.GetResponse();

使用 ASP.net Web API 实现的服务器设置这些 CacheControl header :

response.Headers.CacheControl = new CacheControlHeaderValue
{
MaxAge =3600,
MustRevalidate = true,
Public = true,
Private = true
};

使用带有将请求发送到端点的按钮的测试工具,我可以看到,即使使用了 CacheIfAvailable响应也不会立即缓存。通过检查我的服务器上的调试输出,我发现需要触发一个看似随机的命中数(或者更可能是命中数/运行时间启发式)在最终缓存请求之前。如果我快速敲击测试按钮,它会在 大约 10 次点击后 开始缓存。如果我每 1 秒或 2 秒点击一次按钮,我就会计算出在缓存启动前最多点击 25 次

这是我从 Fiddler 看到的响应:

HTTP/200 responses are cacheable by default, unless Expires, Pragma, or Cache-Control headers are present and forbid caching.
HTTP/1.1 Cache-Control Header is present: public, must-revalidate, max-age=3600, private
private: This response MUST NOT be cached by a shared cache.
public: This response MAY be cached by any cache.
max-age: This resource will expire in 1 hours. [3600 sec]
must-revalidate: After expiration, the server MUST be contacted to verify the freshness of this resource.

HTTP/1.1 ETAG Header is present: "3488770a-8659-4fc0-b579-dcda9200a1c7"

我读过 HttpWebRequest 使用 WinInet 进行缓存,所以我很好奇 WinInet 如何确定何时需要缓存某些内容,更具体地说,为什么它不在第一次点击时缓存?

最佳答案

我使用 RequestCacheLevel.Default 否则我发现 Wininet 会很乐意提供陈旧的响应。

我也不使用 must-revalidate,因为我假设这是缓存响应过时后的默认行为。

我相信如果您始终在请求中包含 LastModifed 或 Etag,那么默认情况下您将获得本地副本,直到它过期(因为您设置了 Private 和 MaxAge),一旦它过期,您可能会返回 304在这种情况下,它将使用本地副本。

说了这么多,请检查您对 vary header 的响应。在许多情况下,Vary header 将阻止使用 Wininet,因为它不正确支持 vary header 。


使用这个 Controller ,

  public class PrivateCachingController : ApiController
{
public HttpResponseMessage Get()
{
var response = new HttpResponseMessage()
{
Content = new StringContent("This is cached content")
};
response.Headers.CacheControl = new CacheControlHeaderValue() {MaxAge = new TimeSpan(0,0,0,60)};
return response;
}
}

和这个客户端代码,

var clientHandler = new WebRequestHandler();
clientHandler.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Default);
var client = new HttpClient(clientHandler) { BaseAddress = _BaseAddress };

var response = await client.GetAsync("/PrivateCaching");
var response2 = await client.GetAsync("/PrivateCaching");

当它执行时,网络上只有一个请求。

关于.net - WinInet 如何确定缓存什么以及何时缓存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20272565/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com