Прошу комментарий к Await / Async
Всем примет. Прошу совета, верно ли делаю относительно своих комментариев. И возможные исправления в по части последовательности выполнения кода.
{
var history = await _historyService.GetHistory(_id); // ---- Долгая, но данные нужны уже тут, потому просто жду.
var resultTask = _httpService.RunWithHistoryAsync(history, (int)_id); //---- Долгая, Выполняю в фоне.
SendStopButton(_id);
SetActivity(_id);
var historyTask = _historyService.GetHistory(_id); - история изменилась, но данные нужны позже, выполняю в фоне.
while (!resultTask.IsCompleted) //---- Нужно, иначе перестает показывать прелоад ( что юзер пишет в чат). Он настроен на 3сек, код выплоняеться дольше.
{
await Task.Delay(TimeSpan.FromSeconds(0.5));
SetActivity(_id); //---- сам прелоад
}
var result = await resultTask; //---- не жду в методе SendMessage, тк необходимо максимально сократить время между удалением и новым сообщением. Иначе может выйти так, что historyTask готов и удаление сработает, а result еще не готов и между этими методами пройдет вечность.
MessageDelite(_id, await historyTask); //---- Удаляю последнее сообщение
SendMessage(_id, result); //---- максимально быстро отправляю после удаления
return;
};
- например
Task<List<MessageInfo>> historyTask = Task.Run(() => _historyService.GetHistory(_id));и потом ожидание, равносильноvar historyTask = _historyService.GetHistory(_id);и потом ожидание - Что-то можно улучшить? Я понимаю, что код короткий, но не уверен что делаю лучшим образом эту часть, тк учусь. Спасибо
Ответы (1 шт):
Автор решения: aepot
→ Ссылка
Нет смысла в Task.Run, если вы работаете с асинхронной операцией.
Можно например вынести поллинг в отдельный метод и останавливать его токеном отмены.
private async Task HeartbeatAsync(int id, CancellationToken token)
{
try
{
while (true)
{
SetActivity(id);
await Task.Delay(TimeSpan.FromSeconds(0.5), token);
}
}
catch (OperationCanceledException)
{ }
}
Тогда получится вот так
using CancellationTokenSource cts = new();
Task preload = HeartbeatAsync(_id, cts.Token);
try
{
var history = await _historyService.GetHistory(_id);
var resultTask = _httpService.RunWithHistoryAsync(history, (int)_id);
SendStopButton(_id);
var historyResult = await _historyService.GetHistory(_id);
var result = await resultTask;
MessageDelite(_id, historyResult); // не Delite, в Delete пишется
SendMessage(_id, result);
}
finally
{
cts.Cancel();
}
await preload;
Возможно еще что-то можно оптимизировать, возможно от цикла можно избавиться, но вы не показали что из себя представляют вызываемые методы и какими типами данных они оперируют, особенно SetActivity (при чем тут 3 секунды и т.д.).