Лучший способ конвертировать метод async на основе обратного вызова в ожидаемую задачу

Каким будет лучший способ конвертировать / переносить «classический» asynchronous метод, который использует обратный вызов для чего-то, что возвращает (ожидаемую) задачу?

Например, учитывая следующий метод:

public void GetStringFromUrl(string url, Action onCompleted); 

Единственный способ, которым я знаю, превратить это в метод, возвращающий задачу:

 public Task GetStringFromUrl(string url) { var t = new TaskCompletionSource(); GetStringFromUrl(url, s => t.TrySetResult(s)); return t.Task; } 

Это единственный способ добиться этого?

И есть способ обернуть вызов GetStringFromUrl (url, callback) в самой задаче (т. Е. Сам вызов будет выполняться внутри задачи вместо синхронного)

Ваш код короток, читабельен и эффективен, поэтому я не понимаю, почему вы ищете альтернативы, но я ничего не могу придумать. Я думаю, что ваш подход разумный.

Я также не уверен, почему вы считаете, что синхронная часть в исходной версии в порядке, но вы хотите избежать ее на основе 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.

  • Как ограничить количество одновременных операций асинхронного ввода-вывода?
  • Запуск нескольких задач async и ожидание их завершения
  • Когда использовать Task.Delay, когда использовать Thread.Sleep?
  • Выполнение задачи в фоновом режиме в приложении WPF
  • Должны ли мы переключиться на использование асинхронного ввода-вывода по умолчанию?
  • Почему это асинхронное действие зависает?
  • Выполнение задач параллельно
  • Давайте будем гением компьютера.