调用HttpClient.GetAsync时出错:底层连接已关闭

mar*_*vpc 12 asp.net asynchronous asp.net-web-api

我有一个asp.net MVC网站,它正在使用rest api来接收它的数据.我正在使用异步任务来执行请求,因为每个页面上可能有很多.经过一段时间的正常运行后,网站在尝试接收数据时抛出了以下错误.

底层连接已关闭:发送时发生意外错误.

我读到这可能是由于web.config上的maxconnection设置,但增加这似乎并没有太大的区别.

我也在使用缓存来减少api的负载.缓存任务,以便稍后使用结果.

我发现解决这个问题的唯一方法是回收应用程序池.任何帮助,将不胜感激.

/* Code from page_load */

var currenciesTask = ApiClient.GetAsync<CurrencyListWrapper>("currencies");
var blogArticleTask = ApiClient.GetAsync<BlogArticleListWrapper>("blog/articles", "limit=10");
var seoPageTask = ApiClient.GetAsync<SEOPageListWrapper>("seopages");

await Task.WhenAll(currenciesTask, blogArticleTask, seoPageTask);


/* Code from data access later */

public class ApiClient : HttpClient
{
  public static Task<T> GetAsync<T>(string operation, string query = null, bool cache = true)
  {
    // Check if task is in cache
    string cacheName = null;

    if (cache)
    {
      cacheName = String.Format("{0}_{1}_{2}", operation, query ?? String.Empty, App.GetLanguage());

      var cachedTask = HttpRuntime.Cache[cacheName];

      if (cachedTask != null)
      {
        return (Task<T>)cachedTask;
      }

    }

    // Get data task
    var task = GetAsyncData<T>(operation, query);

    // Add to cache if required
    if (task != null && cache)
    {
      App.AddToCache(cacheName, task);
    }

    return task;
  }

  public static async Task<T> GetAsyncData<T>(string operation, string query = null)
  {
    using (ApiClient client = new ApiClient())
    {
      string url;

      if (query != null)
      {
        url = String.Format("{0}?{1}", operation, query);
      }
      else
      {
        url = String.Format("{0}", operation);
      }

      var response = await client.GetAsync(url);

      return (await response.Content.ReadAsAsync<T>());
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Aka*_*ava 3

这是错误的,

该任务被缓存,以便稍后使用结果。

您应该缓存结果,而不是任务。第一次执行结束时,您的HttpClient任务将关闭,当您尝试检索缓存的任务时,它将不起作用。

public class ApiClient : HttpClient
{
  public static async Task<T> GetAsync<T>(string operation, string query = null, bool cache = true)
  {
    // Check if task is in cache
    string cacheName = null;

    if (cache)
    {
      cacheName = String.Format("{0}_{1}_{2}", operation, query ?? String.Empty, App.GetLanguage());

      T cachedResult = (T)HttpRuntime.Cache[cacheName];

      if (cachedResult!= null)
      {
        return Task.FromResult(cachedResult);
      }

    }

    // Get data task
    var result = await GetAsyncData<T>(operation, query);

    // Add to cache if required
    if (result != null && cache)
    {
      App.AddToCache(cacheName, result);
    }

    return result;
  }

  public static async Task<T> GetAsyncData<T>(string operation, string query = null)
  {
    using (ApiClient client = new ApiClient())
    {
      string url;

      if (query != null)
      {
        url = String.Format("{0}?{1}", operation, query);
      }
      else
      {
        url = String.Format("{0}", operation);
      }

      var response = await client.GetAsync(url);

      return (await response.Content.ReadAsAsync<T>());
    }
  }
}
Run Code Online (Sandbox Code Playgroud)