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

Вложенные методы async/wait

Я пишу библиотеку, которая обертывает вызов сторонней веб-службы и пытаюсь заставить библиотеку использовать новые функции async/await. Каково правильное использование ключевых слов async/wait в следующем примере?

public class MyApi
{
    public Task<ApiResult> DoSomethingAsync()
    {
        return this.DoSomethingCore();
    }

    public async Task<ApiResult> DoSomethingElseAsync()
    {
        return await this.DoSomethingCore();
    }

    private async Task<ApiResult> DoSomethingCore()
    {
        var httpClient = new HttpClient();
        var httpResponseMessage = await httpClient.GetAsync("some url");
        var rawResultText = await httpResponseMessage.Content.ReadAsStringAsync();
        return new ApiResult(rawResultText);        
    }
}

Чтобы мой вызывающий абонент ожидал метод DoSomethingAsync, должен ли этот метод также добавлять к нему ключевые слова async и ожидания? Или это нормально, потому что оно возвращает задачу? Есть ли лучший шаблон для такого рода вложенности?

Я думаю, что метод DoSomethingAsync - правильный способ пойти сюда, правильно ли? Я считаю, что DoSomethingElseAsync кажется неправильным подходом при создании библиотеки.

4b9b3361

Ответ 1

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

Я не уверен, почему DoSomethingAsync просто вызывает DoSomethingCore, так как DoSomethingAsync может быть так же легко async и использовать await.

Существует также общее правило которое вы должны использовать ConfigureAwait(false) в библиотечных методах.

Изменить: Если вам не нужно использовать await, не делайте метод async. async добавит некоторые накладные расходы (отметьте Channel9 для Stephen Toub Zen видео Async Performance). Если вы можете просто вернуть Task (например, DoSomethingAsync), сделайте это так.

Ответ 2

Приведенная ниже формулировка является функциональной, но, вероятно, вызовет дополнительные накладные расходы (из-за наличия вторичного обратного вызова для дополнительного метода асинхронного/ожидаемого.)

public async Task<ApiResult> DoSomethingElseAsync()
{
    return await this.DoSomethingCore();
}

Проще вернуть задачу непосредственно, так как вы всегда можете ожидать эту задачу в другом месте, не имея метода, реализованного как "async". Async/await очень похож на использование "yield return"; он использует некоторую магию компилятора для реализации "yielding", но самому перечислению все равно, как вы его реализуете. Точно так же призыв "ждать" не волнует, как ожидают работы, если это будет возможно.