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

Как документировать исключения методов async?

Пример метода с документацией XML:

// summary and param tags are here when you're not looking.
/// <exception cref="ArgumentNullException>
///    <paramref name="text" /> is null.
/// </exception>
public void Write(string text)
{
    if (text == null)
        throw new ArgumentNullException("text", "Text must not be null.");

    // sync stuff...
}

Write(null) генерирует исключение, как ожидалось. Вот асинхронный метод:

public async Task WriteAsync(string text)
{
    if (text == null)
        throw new ArgumentNullException("text", "Text must not be null.");

    // async stuff...
}

WriteAsync(null), не будет генерировать исключение до тех пор, пока его не ожидают. Должен ли я указывать ArgumentNullException в теге exception? Я думаю, что это заставит потребителя думать, что вызов WriteAsync может вызвать ArgumentNullException и написать что-то вроде этого:

Task t;
try
{
    t = foo.WriteAsync(text);
}
catch (ArgumentNullException)
{
    // handling stuff.
}

Какова наилучшая практика для документирования исключений в асинхронных методах?

4b9b3361

Ответ 1

Не прямой ответ, но лично я бы посоветовал склониться к быстрому провалу; это может означать запись двух методов:

public Task WriteAsync(string text) // no "async"
{
    // validation
    if (text == null)
        throw new ArgumentNullException("text", "Text must not be null.");

    return WriteAsyncImpl(text);
}
private async Task WriteAsyncImpl(string text)
{
    // async stuff...
}

Этот шаблон также является идеальным местом для добавления кода "быстрого пути", например:

public Task WriteAsync(string text) // no "async"
{
    // validation
    if (text == null)
        throw new ArgumentNullException("text", "Text must not be null.");

    if (some condition)
        return Task.FromResult(0); // or similar; also returning a pre-existing
                                   // Task instance can be useful

    return WriteAsyncImpl(text);
}

Ответ 2

Microsoft, похоже, не различает метод async, бросающий исключение, а возвращаемый Task имеет исключение, хранящееся в свойстве Exception. Например:.

WebClient.DownloadFileTaskAsync(string, string)

Лично я хотел бы документировать исключения как часть документации для возвращаемого значения (т.е. возвращенного Task), поскольку различие может быть важным для клиентов.