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

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

Например, дан следующий метод:

public void GetStringFromUrl(string url, Action<string> onCompleted);

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

public Task<string> GetStringFromUrl(string url)
{
     var t = new TaskCompletionSource<string>();

     GetStringFromUrl(url, s => t.TrySetResult(s));

     return t.Task;
}

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

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

2 ответа

Решение

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

Я также не уверен, почему вы думаете, что синхронная часть хорошо в оригинальной версии, но вы хотите избежать этого в Task на основе Если вы считаете, что синхронная часть может занять слишком много времени, исправьте ее для обеих версий метода.

Но если вы хотите запустить его асинхронно (т.е. на ThreadPool) только в Task версия, вы можете использовать Task.Run():

public Task<string> GetStringFromUrl(string url)
{
    return Task.Run(() =>
    {
        var t = new TaskCompletionSource<string>();

        GetStringFromUrl(url, s => t.TrySetResult(s));

        return t.Task;
    });
}

Ваша предполагаемая реализация вполне подходит для этого, если предположить, что обратный вызов только когда-либо обрабатывает успешные ситуации. Что в настоящее время происходит, если исключение происходит внутри асинхронных основ реализации GetStringFromUrl? У них нет реального способа передать это обратному вызову Action... они просто проглатывают его и возвращают ноль или что-то еще?

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

Другие вопросы по тегам