Ответ 1
Я собираюсь использовать их в приложении командной строки. Поэтому мне нужно много раз им звонить.
Нет, ты не Вы можете использовать async
- await
в консольном приложении, вам просто нужно сделать асинхронный переход для синхронизации на самом верху. И вы можете сделать это, используя Wait()
:
public static void Main()
{
MainAsync().Wait();
}
public static async Task MainAsync()
{
var datastore = …;
await datastore.SaveAsync();
}
Обычно объединение await
с Wait()
является плохой идеей (она может вызвать взаимные блокировки), но здесь это правильное решение.
Обратите внимание, что если SaveAsync()
выдает исключение, и вы его не перехватываете, оно будет переброшено как AggregateException
из Wait()
. Но вы можете поймать его как исходное исключение в MainAsync()
(потому что он не использует Wait()
).
Если вы действительно хотите получить первое исключение напрямую, вы можете сделать что-то похожее на то, что делает await
: task.GetAwaiter().GetResult()
. Обратите внимание, что если Task
содержит более одного исключения, вы получите только первое (но то же самое относится и к await
).
Начиная с С# 7.1, вы можете сделать свой метод Main
async
, и компилятор напишет код перехода для вас:
public static async Task Main()
{
var datastore = …;
await datastore.SaveAsync();
}
Когда я использую метод, возвращающий
Task<TResult>
,task.Result
выбрасываетAggregateException
, даже если не заданы задачи продолжения. Почему это происходит?
Это не имеет ничего общего с продолжениями. Один Task
может представлять несколько операций, и каждая из них может выдать исключение. Из-за этого методы Task
всегда выдают исключения, заключенные в AggregateException
.
Я также попробовал
task.RunSynchronously()
В этом нет смысла. RunSynchronously()
можно использовать только на Task
, которые были созданы с помощью конструктора Task
. Это не тот случай, поэтому вы не можете его использовать. Task
, возвращаемый из асинхронных методов, всегда уже запущен.