Лучший способ конвертировать метод 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.

  • Секвенирование и реорганизация задач
  • Шаблон для самоотдачи и перезапуска задачи
  • Вызов синхронного асинхронного метода
  • Как ограничить количество одновременных операций асинхронного ввода-вывода?
  • Запуск двух асинхронных задач параллельно и сбор результатов в .NET 4.5
  • Использовать Task.Run () в синхронном методе, чтобы избежать тупиковой остановки в асинхронном методе?
  • WaitAll vs WhenAll
  • Давайте будем гением компьютера.