Не очень силён в async/await, не могу понять, что мне студия советует сделать.
public class ManagerService
{
public ManagerService()
{
Task.Run(Observe);
}
private async Task Observe()
{
while (true)
{
Thread.Sleep(5000);
Debug.WriteLine("Observe");
}
}
}
"В данном асинхронном методе отсутствуют операторы await, поэтому метод будет выполняться синхронно. Воспользуйтесь оператором await для ожидания неблокирующих вызовов API или оператором await Task.Run(...) для выполнения связанных с ЦП заданий в фоновом потоке."
await в моём понимание мне не нужен, так как я ждать чего либо не собираюсь, просто запускаю процесс в фоновом потоке. Использовать "await Task.Run(...)" не получается (возможно не правильно это пытаюсь сделать), и не понимаю, что это мне даст.
Вообщем вопрос в том, что я теряю, если оставляю как есть?
async/await в методе Observe
вам вроде бы действительно не нужен. Поскольку в нем не используется ключевое слово await
, то Студия говорит вам о том, что и async Task
не нужен. Должно получиться так:
private void Observe()
{
while (true)
{
Thread.Sleep(5000);
Debug.WriteLine("Observe");
}
}
Если вы решите оставить ключевое слово async
, то теряете маленькие крохи на производительности, поскольку для таких методов компилятор генерирует специальный код, вызов которого стоит дороже, чем вызов обычного метода.
Однако в методе есть один недостаток: при вызове Thread.Sleep()
поток будет блокироваться и простаивать без работы. Это не очень хорошо (а иногда и вообще критично). Здесь нам как раз может помочь асинхронный вариант ожидания: Task.Delay
. И теперь async/await снова имеет смысл:
private async Task ObserveAsync()
{
while (true)
{
await Task.Delay(5000).ConfigureAwait(false);
Debug.WriteLine("Observe");
}
}
Подробнее о том, как работает async/await и почему блокировать потоки плохо, можно почитать в другом ответе или посмотреть доклад.
Другой момент: завершение метода. Если у вас есть бесконечный цикл, то нужно предусмотреть выход из него. И если логика метода такого не предполагает, то нужно использовать некую команду извне. Для этого рекомендуется использовать CancellationToken
(при этом его можно использовать как в синхронном, так и в асинхронном варианте):
// не забудьте по окончании работы вызвать Dispose()
CancellationTokenSource tokenSource = new CancellationTokenSource();
public ManagerService()
{
Task.Run(Observe);
}
private void Observe()
{
while (!tokenSource.Token.IsCancellationRequested)
{
Thread.Sleep(5000);
Debug.WriteLine("Observe");
}
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Видел примеры на различных языках, но для c# не понял как это реализовать, прошу помощиЕсть текст, к примеру 20 символов
У меня есть простой апи контроллер, который я показал вышеНо каждый сможет прописать (пример - не тыкайте)"https://www
Здравствуйте, пишу программу которая получает фотографию, и рисует ее на консоли, но поскольку приложение консольное, а как вы знаете что...