Иногда я использую набор задач, и чтобы убедиться, что все они ожидаются, я использую этот подход:
public async Task ReleaseAsync(params Task[] TaskArray)
{
var tasks = new HashSet<Task>(TaskArray);
while (tasks.Any()) tasks.Remove(await Task.WhenAny(tasks));
}
, а затем называю это так:
await ReleaseAsync(task1, task2, task3);
//or
await ReleaseAsync(tasks.ToArray());
Однако недавно я заметил странное поведение и решил посмотреть, не возникла ли проблема с методом ReleaseAsync. Мне удалось сузить его до этого простого демо, оно работает в linqpad, если вы включите System.Threading.Tasks
. Он также будет работать слегка измененным в консольном приложении или в контроллере asp.net mvc.
async void Main()
{
Task[] TaskArray = new Task[]{run()};
var tasks = new HashSet<Task>(TaskArray);
while (tasks.Any<Task>()) tasks.Remove(await Task.WhenAny(tasks));
}
public async Task<int> run()
{
return await Task.Run(() => {
Console.WriteLine("started");
throw new Exception("broke");
Console.WriteLine("complete");
return 5;
});
}
Чего я не понимаю, так это того, почему Исключение нигде не появляется. Я бы подумал, что если бы Задачи за исключением ожидали, он бы бросил. Я смог подтвердить это, заменив цикл while простым для каждого следующим образом:
foreach( var task in TaskArray )
{
await task;//this will throw the exception properly
}
Мой вопрос: почему показанный пример не генерирует исключение должным образом (он нигде не отображается) .