Я думал, что задача GetData
, зарегистрированная в Page_Load
, не будет блокировать загрузку Index.aspx
, поскольку это асинхронная задача; Через 5 секунд после рендеринга страницы lblData устанавливается и отражается в Index.aspx
.
Однако в моем случае загрузка Index.aspx
заблокирована на 5 секунд, ожидая завершения async GetData
. Только через 5 секунд визуализируется Index.aspx
.
Ожидается ли это? Или GetData
работает синхронно, потому что я сделал что-то не так?
// Index.aspx.cs
public partial class Index : Page
{
protected string lblData;
protected void Page_Load(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(GetData));
ExecuteRegisteredAsyncTasks();
}
public async Task GetData()
{
await Task.Delay(5000);
lblData = "Hello world!";
}
// ...
}
Я добавил Async="true"
в Index.aspx
.
3 ответа
«Асинхронный» - это модификатор. Вы всегда должны спрашивать "асинхронность относительно чего?"
В этом случае задача является асинхронной по отношению к рабочим потокам, обслуживающим запросы. Важным моментом является то, что вам не нужно блокировать поток запросов при обработке большинства видов асинхронных задач, поэтому ваш сервер при прочих равных условиях сможет обслуживать больше запросов одновременно, при этом, возможно, используя для этого меньше ресурсов.
Это не асинхронно относительно рендеринга страницы на клиенте или даже самого отдельного запроса - обработка запроса по-прежнему полностью синхронна и будет отправлена только тогда, когда будет готов весь ответ (если вы не используете явные Flush
es, но это уже целая банка червей). Фактически, весь смысл await
состоит в том, чтобы позволить вашему коду вести себя так, как если бы он был синхронным, но в то же время асинхронным по отношению к потокам, вводу-выводу, пользовательскому интерфейсу и т. Д. await
- явная точка синхронизации.
Фактически, именно поэтому вы в первую очередь используете асинхронную инфраструктуру. Если вы использовали асинхронные задачи без RegisterAsyncTask
, запрос завершился бы до того, как ответ будет полностью выполнен. Инфраструктура позволяет вам освобождать рабочие потоки, пока они вам не нужны, сохраняя при этом весь соответствующий контекст запроса готовым к тому времени, когда вы вернетесь из своей асинхронной работы. Это похоже на использование await
в методе Main
консольного приложения - если инфраструктура не готова, await
просто означает return someTask;
без "и вернуться сюда, когда задача сделана ».
Если вам нужно что-то, что не блокирует обработку запроса, оно должно быть асинхронным по отношению к запросу . Например, страница может отправить серверу отдельный запрос AJAX для предоставления дополнительных данных.
Вероятно, он работает асинхронно, но он все еще «код позади», и этот код будет запущен и завершен на сервере до того, как любая отрисованная страница будет отправлена в браузер.
Если вы хотите, чтобы ваша сетка динамически заполнялась после загрузки страницы в браузере, вам нужно использовать JavaScript и WebMethods или WebAPI или что-то подобное.
Согласно MSDN, вы все делаете правильно. Я предполагаю, что вы ошибочно предполагаете, что страница будет загружена / обработана и возвращена клиенту до завершения асинхронной операции, определенной в функции GetData
- если это так, это неверно.
Жизненный цикл (в то время как асинхронный) по-прежнему не возвращается клиенту, пока не будет выполнена вся работа. Вот SO Q & amp;, что может иметь больше смысла. Еще лучшее объяснение Скотта Хансельмана здесь.
Похожие вопросы
Связанные вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.