为什么没有这种异常抛出? [英] Why doesn't this exception get thrown?

查看:144
本文介绍了为什么没有这种异常抛出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用的是定在次任务,并为了确保他们都期待我用这种方式:

I use a set of tasks at times, and in order to make sure they are all awaited I use this approach:

public async Task ReleaseAsync(params Task[] TaskArray)
{
  var tasks = new HashSet<Task>(TaskArray);
  while (tasks.Any()) tasks.Remove(await Task.WhenAny(tasks));
}

然后调用它是这样的:

and then call it like this:

await ReleaseAsync(task1, task2, task3);
//or
await ReleaseAsync(tasks.ToArray());

不过,最近我已经注意到一些奇怪的行为,设置,看看是否有与ReleaseAsync方法的问题。我设法缩小它这个简单的演示,它linqpad运行,如果包括 System.Threading.Tasks 。它会工作也略作修改的控制台应用程序或一个asp.net mvc的控制器。

However, recently I have been noticing some strange behavior and set to see if there was a problem with the ReleaseAsync method. I managed to narrow it down to this simple demo, it runs in linqpad if you include System.Threading.Tasks. It will also work slightly modified in a console app or in an asp.net mvc controller.

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;
 });
}

我不明白的是,为什么异常从来没有在任何地方显示出来。我会想,如果有异常的任务是期待已久,它会抛出异常。我可以用一个简单的替换,而循环为每个这样的证实了这一点:

What I don't understand is why the Exception never shows up anywhere. I would have figured that if the Tasks with the exception were awaited, it would throw. I was able to confirm this by replacing the while loop with a simple for each like this:

foreach( var task in TaskArray )
{
  await task;//this will throw the exception properly
}

我的问题是,为什么不显示例子正确抛出异常(它永远不会显示出来的任何地方)。

My question is, why doesn't the shown example throw the exception properly (it never shows up anywhere).

推荐答案

TL; DR 的run()抛出异常,但你再等待 WhenAny(),不抛出异常本身。

TL;DR: run() throws the exception, but you're awaiting WhenAny(), which doesn't throw an exception itself.

MSDN文档 WhenAny 规定:

The MSDN documentation for WhenAny states:

返回的任务将完成任何时候所提供的任务已经完成。返回的任务将永远结束​​在 RanToCompletion 的状态,其结果设置为第一个任务来完成。这是真实的,即使到完成结束了第一个任务在取消断陷状态。

The returned task will complete when any of the supplied tasks has completed. The returned task will always end in the RanToCompletion state with its Result set to the first task to complete. This is true even if the first task to complete ended in the Canceled or Faulted state.

从本质上正在发生的事情是,通过 WhenAny 返回的任务只是燕子出现故障的任务。它只在乎这些任务完成后,并不在于它已经成功地完成了这一事实。当你等待的任务,它只是完成没有错误,因为它是内部的任务,出现了故障,而不是你等待的人。

Essentially what is happening is that the task returned by WhenAny simply swallows the faulted task. It only cares about the fact that the task is finished, not that it has successfully completed. When you await the task, it simply completes without error, because it is the internal task that has faulted, and not the one you're awaiting.

这篇关于为什么没有这种异常抛出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆