Лучший способ конвертировать метод async на основе обратного вызова в ожидаемую задачу
Каким будет лучший способ конвертировать / переносить «classический» asynchronous метод, который использует обратный вызов для чего-то, что возвращает (ожидаемую) задачу?
Например, учитывая следующий метод:
public void GetStringFromUrl(string url, Action onCompleted);
Единственный способ, которым я знаю, превратить это в метод, возвращающий задачу:
- ConfigureAwait подталкивает продолжение в stream пула
- Почему это асинхронное действие зависает?
- Выполнение задач параллельно
- Запуск нескольких задач async и ожидание их завершения
- Выполнение задачи в фоновом режиме в приложении WPF
public Task GetStringFromUrl(string url) { var t = new TaskCompletionSource(); GetStringFromUrl(url, s => t.TrySetResult(s)); return t.Task; }
Это единственный способ добиться этого?
И есть способ обернуть вызов GetStringFromUrl (url, callback) в самой задаче (т. Е. Сам вызов будет выполняться внутри задачи вместо синхронного)
- Должны ли мы переключиться на использование асинхронного ввода-вывода по умолчанию?
- В чем разница между возвратом пустоты и возвратом задачи?
- Очередь процесса с многопоточным или задачами
- Когда использовать Task.Delay, когда использовать Thread.Sleep?
- Разница между TPL и async / await (Обработка streamов)
- Отмена ожидающей задачи синхронно в streamе пользовательского интерфейса
- Запуск задач в foreach Loop использует значение последнего элемента
- Каков правильный способ отмены асинхронной операции, которая не принимает CancellationToken?
Ваш код короток, читабельен и эффективен, поэтому я не понимаю, почему вы ищете альтернативы, но я ничего не могу придумать. Я думаю, что ваш подход разумный.
Я также не уверен, почему вы считаете, что синхронная часть в исходной версии в порядке, но вы хотите избежать ее на основе Task
. Если вы считаете, что синхронная часть может занять слишком много времени, исправьте ее для обеих версий метода.
Но если вы хотите запустить его асинхронно (т.е. на ThreadPool
) только в версии Task
, вы можете использовать Task.Run()
:
public Task GetStringFromUrl(string url) { return Task.Run(() => { var t = new TaskCompletionSource (); GetStringFromUrl(url, s => t.TrySetResult(s)); return t.Task; }); }
Ваша предполагаемая реализация отлично подходит для этого, предполагая, что обратный вызов только когда-либо обрабатывает успешные ситуации. Что происходит, если исключение происходит в рамках async-подтекстов реализации GetStringFromUrl? Нет никакого реального способа для них распространять это на обратный вызов Action … они просто проглатывают его и возвращают вам нуль или что-то еще?
Единственное, что я рекомендовал бы, это использовать следующее соглашение об именах таких методов async с суффиксом XXXAsync.