Подтвердить что ты не робот

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

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

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

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) в самой задаче (т.е. сам вызов будет выполняться внутри задачи вместо синхронного)

4b9b3361

Ответ 1

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

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

Ответ 2

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

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