Асинхронный API-метод с использованием AsyncRequestHandler слишком много потоков? [Дубликат]

Альтернативное решение заключается в использовании Apache Commons ' NumberUtils:

int num = NumberUtils.toInt("1234");

Утилита Apache хороша, потому что, если строка является недопустимым числовым форматом, тогда 0 всегда возвращается , Следовательно, вы сохраняете блок catch try.

Apache NumberUtils API Version 3.4

152
задан TX_ 30 September 2013 в 16:30
поделиться

5 ответов

Выполняя иначе простой метод «thunk», async создает в памяти состояние async state machine, а не async - нет. Хотя это часто может указывать на использование версии non-async, поскольку она более эффективна (это правда), это также означает, что в случае зависания у вас нет доказательств того, что этот метод задействован в «стеке возврата / продолжения», что иногда затрудняет понимание повесы.

Итак, да, когда perf не критичен (и обычно это не так), я брошу async на все эти методы thunk, чтобы у меня была машина состояния async, чтобы помочь мне диагностировать зависания позже, и также, чтобы гарантировать, что, если эти методы thunk когда-либо будут развиваться со временем, они обязательно вернут сбитые задачи вместо throw.

10
ответ дан Andrew Arnott 31 August 2018 в 10:23
поделиться

Это также смущает меня, и я чувствую, что предыдущие ответы не учитывали ваш фактический вопрос:

Зачем использовать конструкцию return wait, когда вы можете напрямую возвращать задачу из внутреннего вызова DoAnotherThingAsync ()?

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

Из вашего кода:

async Task<SomeResult> DoSomethingAsync()
{
    using (var foo = new Foo())
    {
        return await foo.DoAnotherThingAsync();
    }
}

Человек, незнакомый с синтаксисом (например, я), может подумать, что этот метод должен возвращать Task<SomeResult>, но поскольку он помечен как async, это означает, что его фактический тип возврата SomeResult. Если вы просто используете return foo.DoAnotherThingAsync(), вы возвращаете задачу, которая не будет компилироваться. Правильный способ - вернуть результат задачи, поэтому return await.

2
ответ дан heltonbiker 31 August 2018 в 10:23
поделиться

Единственная причина, по которой вы захотите это сделать, - это если в предыдущем коде есть еще один await или если вы каким-то образом обработаете результат перед его возвратом. Другой способ, которым это может происходить, - это try/catch, который изменяет порядок обработки исключений. Если вы ничего не делаете, тогда вы правы, нет причин добавлять накладные расходы на создание метода async.

20
ответ дан Servy 31 August 2018 в 10:23
поделиться

Если вам не нужно async (т. е. вы можете напрямую вернуть Task), тогда не используйте async.

Есть ситуации, когда return await полезно, например, если у вас есть две асинхронные операции :

var intermediate = await FirstAsync();
return await SecondAwait(intermediate);

Дополнительные сведения о производительности async см. в статье MSDN Стивена Тоуба и video по этой теме.

Обновление: я написал сообщение в блоге , которое идет гораздо подробнее.

54
ответ дан Stephen Cleary 31 August 2018 в 10:23
поделиться

Существует один подлый случай, когда return в обычном методе и return await в async метод ведут себя по-другому: в сочетании с using (или, в более общем смысле, любой return await в блоке try), .

Рассмотрим эти две версии метода:

Task<SomeResult> DoSomethingAsync()
{
    using (var foo = new Foo())
    {
        return foo.DoAnotherThingAsync();
    }
}

async Task<SomeResult> DoSomethingAsync()
{
    using (var foo = new Foo())
    {
        return await foo.DoAnotherThingAsync();
    }
}

Первый метод будет Dispose() объектом Foo, как только метод DoAnotherThingAsync() вернется, что вероятно, задолго до его завершения. Это означает, что первая версия, вероятно, глючит (потому что Foo находится слишком рано), а вторая версия будет работать нормально.

124
ответ дан svick 31 August 2018 в 10:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: