HttpClient在服务器上启用缓存

时间:2017-12-08 13:10:13

标签: .net caching asp.net-web-api dotnet-httpclient

我正在尝试启用System.Net.HttpClient的客户端缓存。我在http://localhost:83/api/test有一个端点需要1秒钟才能响应,它会重新发送缓存头。

如果我有这段代码

static async Task MainAsync()
{
    var client = new HttpClient(new WebRequestHandler { CachePolicy = new HttpRequestCachePolicy() }) { BaseAddress = new Uri("http://localhost:83/api/") };
    for (int i = 0; i < 20; i++)
    {
        var response = await client.GetAsync("test");
        var res = await response.Content.ReadAsStringAsync();
        Console.WriteLine(res);
    }
}

执行需要一秒钟。

如果我将相同的代码放入api控制器

    static HttpClient client = new HttpClient(new WebRequestHandler {CachePolicy = new HttpRequestCachePolicy() }) { BaseAddress = new Uri("http://localhost:83/api/") };
    public async Task<string> Get()
    {
        for (int i = 0; i < 20; i++)
        {
            var response = await client.GetAsync("test");
            var res = await response.Content.ReadAsStringAsync();
        }
        return "ok";
    }

在IIS中托管它需要20秒才能响应。

为了从服务器应用程序启用客户端缓存,我需要做什么?

3 个答案:

答案 0 :(得分:2)

可能你应该切换到WinHTTP并使用另一个HTTP缓存实现。

.NET Framework使用两种HTTP客户端API。一个由WinINet提供,另一个由WinHTTP提供。 .NET Framework默认使用WinINet。但WinINet开发用于客户端应用程序,并不假设在服务器环境中工作。 MSDN上Windows Internet页面的相关引用:

  

适用时

     

WinINet不支持服务器实现。此外,它不应该从服务中使用。对于服务器实现或服务,请使用Microsoft Windows HTTP Services (WinHTTP)

因此,在Web API中,您需要使用WinHTTP。我知道切换的唯一方法是使用System.Net.Http.WinHttpHandler NuGet包中的WinHttpHandler。但是目前这个处理程序不使用HTTP缓存。它无法设置缓存策略,它会忽略HttpClientHandler尊重的所有设置。请参阅GitHub上的How do I utilize HTTP caching with WinHttpHandler and HttpClient?问题。

要解决此问题,您可以实现自己的缓存机制或使用现有的CacheCow项目。它具有内置的内存存储,并且DelagatingHandlerHttpClient实现了WinHttpHandler。  请注意,目前存在一些兼容性问题,您需要在安装System.Net.Http.WinHttpHandler和CacheCow.Clien NuGet包之前从Web API项目中手动删除对.NET Framework System.Net.Http的引用。以下代码剪辑演示了CacheCow.Clien NuGet包中CachingHandlerstatic HttpClient client = new HttpClient(new CachingHandler { InnerHandler = new WinHttpHandler() }) { BaseAddress = new Uri("http://localhost:83/api/") }; 的用法:

justify-content:space-around

有关详细信息,请查看:

答案 1 :(得分:0)

您的网站运行的应用程序池没有与之关联的用户配置文件,或者在配置文件中的某处禁止缓存。

为了在IIS中使用该缓存机制,您需要将用户配置文件与应用程序池相关联,以便您的网站可以利用该配置文件的临时文件文件夹。有关详细信息,请参阅Chris Oldwood的IIS Hosted Web API Not Caching Internal HTTP Responses文章。 MSDN上Application Pool Identities页面的相关引用:

  

用户个人资料

     

IIS不会加载Windows用户配置文件,但某些应用程序可能会利用它来存储临时数据。 SQL Express是执行此操作的应用程序的示例。但是,必须创建用户配置文件以将临时数据存储在配置文件目录或注册表配置单元中。网络服务帐户的用户配置文件由系统创建,始终可用。但是,通过切换到唯一的应用程序池标识,系统不会创建任何用户配置文件。只有标准应用程序池(DefaultAppPool和Classic .NET AppPool)在磁盘上具有用户配置文件。如果管理员创建新的应用程序池,则不会创建用户配置文件。

     

但是,如果需要,可以通过将LoadUserProfile属性设置为&#34; true&#34;来配置IIS应用程序池以加载用户配置文件。

还可以通过Web或计算机配置文件中的disableAllCaching标志禁用嵌入式缓存机制。您还需要检查此项,因为无法以编程方式覆盖此设置。

答案 2 :(得分:0)

作为重新配置服务器的替代方法,您可以自己缓存结果 - 也可以根据需要将其存储在会话中。

话虽如此,你已经将异步调用转变为阻塞调用 - 你应该使用回调(或承诺)。