我有一个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>());
}
}
}
答案 0 :(得分: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>());
}
}
}
答案 1 :(得分:0)
阿卡什可能是对的。 但似乎或多或少与应用程序池的连接问题。设置连接限制0以使其在应用程序池中无限制。 在代码中有一个finally块,
gc.collect();
要调用的垃圾收集方法,以删除未使用的连接以为其他连接腾出空间。