Альтернативное решение заключается в использовании Apache Commons ' NumberUtils:
int num = NumberUtils.toInt("1234");
Утилита Apache хороша, потому что, если строка является недопустимым числовым форматом, тогда 0 всегда возвращается , Следовательно, вы сохраняете блок catch try.
Выполняя иначе простой метод «thunk», async создает в памяти состояние async state machine, а не async - нет. Хотя это часто может указывать на использование версии non-async, поскольку она более эффективна (это правда), это также означает, что в случае зависания у вас нет доказательств того, что этот метод задействован в «стеке возврата / продолжения», что иногда затрудняет понимание повесы.
Итак, да, когда perf не критичен (и обычно это не так), я брошу async на все эти методы thunk, чтобы у меня была машина состояния async, чтобы помочь мне диагностировать зависания позже, и также, чтобы гарантировать, что, если эти методы thunk когда-либо будут развиваться со временем, они обязательно вернут сбитые задачи вместо throw.
Это также смущает меня, и я чувствую, что предыдущие ответы не учитывали ваш фактический вопрос:
Зачем использовать конструкцию return wait, когда вы можете напрямую возвращать задачу из внутреннего вызова DoAnotherThingAsync ()?
blockquote>Ну, иногда вы на самом деле хотите
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
.
Единственная причина, по которой вы захотите это сделать, - это если в предыдущем коде есть еще один await
или если вы каким-то образом обработаете результат перед его возвратом. Другой способ, которым это может происходить, - это try/catch
, который изменяет порядок обработки исключений. Если вы ничего не делаете, тогда вы правы, нет причин добавлять накладные расходы на создание метода async
.
Если вам не нужно async
(т. е. вы можете напрямую вернуть Task
), тогда не используйте async
.
Есть ситуации, когда return await
полезно, например, если у вас есть две асинхронные операции :
var intermediate = await FirstAsync();
return await SecondAwait(intermediate);
Дополнительные сведения о производительности async
см. в статье MSDN Стивена Тоуба и video по этой теме.
Обновление: я написал сообщение в блоге , которое идет гораздо подробнее.
Существует один подлый случай, когда 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
находится слишком рано), а вторая версия будет работать нормально.