async public Task CreatePresentation
содержит строку кода
using (var response = await client.SendAsync(request).ConfigureAwait(false))
Предположим, завершение этой строки занимает 10 секунд. Пока это происходит, клиент хочет перейти на другой URL-адрес внутри веб-сайта и щелкает по этому URL-адресу (это представление также является асинхронным, что означает, что это асинхронное общедоступное Task BRDetails(int id)). Но ASP.NET не предоставляет ему представление немедленно.
Вместо этого он ожидает завершения строки await, прежде чем предоставить ему представление (10 секунд).
Почему платформа ASP.NET ждет завершения строки await, прежде чем начнет создавать представление для следующего URL-адреса, запрошенного клиентом?
Я думал, что доставка следующего URL-адреса должна начинаться немедленно во втором потоке и сначала ожидает завершения await из-за .ConfigureAwait(false).
Среда:
- .NET Framework v4.5,
- IIS Express, входящий в состав Visual Studio
async public Task CreateReportFile(int id, string email)
{
try
{
var fileName = "Report " + DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss") + ".txt";
fileName = fileName.Replace('/', '_');
fileName = fileName.Replace(':', '_');
var fullPath = "some path";
var presentationTask = new Creator().CreateSomeFile("some values to pass", fileName);
var ms = await presentationTask.ConfigureAwait(false);
using (FileStream file = new FileStream(fullPath, FileMode.Create, System.IO.FileAccess.Write))
{
ms.WriteTo(file);
ms.Close();
}
var emailAttachment = BusinessReportsEmail.savePresentation(fullPath, fileName);
await BusinessReportsEmail.sendEmail(emailAttachment, email).ConfigureAwait(false);
return Json(new
{
Status = "ok",
Data = email
});
}
catch (Exception ex)
{
return Json(new
{
Status = "error",
Data = ex.Message
});
}
}
public async Task CreateSomeFile(string programData, string outputFileName)
{
// Use this in production
var url = string.Format(System.Configuration.ConfigurationManager.AppSettings["workFileUrl"]);
var appCode = string.Format(System.Configuration.ConfigurationManager.AppSettings["appCode"]);
var appKey = string.Format(System.Configuration.ConfigurationManager.AppSettings["appKey"]);
using (var client = new HttpClient())
{
client.Timeout = TimeSpan.FromMinutes(20);
using (var request = new HttpRequestMessage(HttpMethod.Post, url))
{
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Add("AppCode", appCode);
request.Headers.Add("AppKey", appKey);
var jsonString = JsonConvert.SerializeObject(new
{
InputType = "json",
Content = programData
});
request.Content = new StringContent(jsonString, Encoding.UTF8, "application/json");
using (var response = await client.SendAsync(request).ConfigureAwait(false))
{
var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception($"Failed to create {outputFileName} file.");
var reponseObject = await response.Content.ReadAsAsync().ConfigureAwait(false);
return new MemoryStream(Convert.FromBase64String(reponseObject.Content));
}
}
}
}
И затем клиент переходит к этому представлению, но ему нужно дождаться завершения предыдущего вызова:
async public Task ReviewDetails(int id)
{
return View();
}
Подробнее здесь: https://stackoverflow.com/questions/691 ... false-to-f
Мобильная версия