Можно ли как-нибудь вызвать по таймеру асинхронную функцию в C#? У обычного System.Threading.Timer callback-функция не может быть асинхронной, но, может, существуюут какие-нибудь другие способы?
С таймером и асинхронными методами надо быть аккуратнее. Как вы верно заметили, Timer не поддерживает асинхронные методы, а потому предложенный в другом ответе способ естественно имеет недостатки. TimerCallback -- это void-метод, т.е. по сути вы передаете async void метод. Отсюда два следствия:
Таймер не будет дожидаться завершения функции, что может привести к нежелательным последствиям (например, вызовы будут накладываться друг на друга).
Поскольку метод не ожидается, то и об исключениях в нем тоже никто не узнает. Обязательно нужно обрабатывать ошибки в самом методе, иначе исключение в пуле потоков может привести к завершению приложения (впрочем, этот пункт относится и к синхронным делегатам).
Встроенной поддержки регулярного запуска асинхронной функции в .NET пока нет. Самый простой вариант - написать метод с использованием бесконечного цикла и Task.Delay. Это по-настоящему асинхронный вариант периодического запуска асинхронного метода. Код может выглядеть так:
public async Task RunPeriodicallyAsync(
Func<Task> func,
TimeSpan interval,
CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
await Task.Delay(interval, cancellationToken)
await func();
}
}
Сюда по желанию/необходимости можно добавлять обработку ошибок, ConfigureAwait(false) и все, что еще понадобится.
В Timer можно передать асинхронный делегат, в коде выглядеть это будет так:
System.Threading.Timer timer = new Timer(async state =>
{
await Task.Delay(500);
});
Я у себя в коде под Андроид сделал так:
_timerUniversal = new Timer(CheckUniversal, _startTime, 0, TimerWait);
async Task<int> CallAll()
{
await CheckNewUserCallback();
await CheckNewGroupCallback();
await CheckNewMessagesCallback();
await WriteMessagesFromChannels();
await AddChannelUsers();
return 1;
}
void CheckUniversal(object state)
{
var rc = CallAll();
}
Не знаю, насколько это правильно, но, вроде, работает.
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости