Почему это исключение не выбрасывается?

Иногда я использую набор задач, и чтобы убедиться, что все они ожидаются, я использую этот подход:

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
}

Мой вопрос: почему показанный пример не генерирует исключение должным образом (он нигде не отображается) .

8
задан Yuval Itzchakov 5 February 2015 в 07:16
поделиться