【问题标题】:"finally" not executed because of Async in "try"?由于“try”中的异步,“finally”没有执行?
【发布时间】:2016-11-03 00:20:42
【问题描述】:

我有一个 bool (b),它在我的代码中只出现了两次(除了它的声明):

try 
{
    b = true;
    //code including await SomeAsync();
}
catch {  }
finally { b = false; }

但有时 try 块 开始btrue (-之前 b = true) 这不应该是发生是因为声明离开它false,就像之前的finally 一样。在某些时候,此代码在循环中执行,在某些情况下迭代速度很快,SomeAsync() 试图使用过多的内存。我认为这是引发可以“破坏”finally 的类型的异常。 (b 始终是 false,当只有正常数量的数据供 SomeAsync() 处理时。)

我已经尝试验证 Visual Studio 在tryfinally 之后使用Debug.WriteLine() 向我显示的内容,并且还通过在这些位置附加一个不同字符的字符串,然后是finally 被执行。所以我认为缓慢的延迟足以防止异常。

这真的可能吗? (关于如何验证或修复它以使 finally 始终运行的任何想法?)

(最终阻止 可以 失败 - 案例:Conditions when finally does not execute in a .net try..finally block

编辑

在评论和答案中提出了一个很好的观点——这段代码可能会在awaits 期间同时执行多次。不幸的是,还有另一个细节(这些答案让我意识到是相关的)——在所有迭代之后——状态是btrue不能用并发来解释。我还在try 块之前添加了一个if (b) return;(以避免在前一个运行时调用Async)。在所有迭代完成后,仍然留下true b

【问题讨论】:

  • 如果 b = true 是 try 块中的第一行,它将始终运行,因为 b = true 不会失败。 try 块一直运行直到失败。
  • @EliSadoff 这是true 那一行之前。
  • “我认为这是导致异常的原因” - 什么异常?
  • 您是否有可能调用a re-entrant way 中的函数?所以它还在等待await SomeAsync() 完成它被第二次调用?
  • 为了解决你的问题,如果你有一个任务永远不会完成,那会导致它被卡住,但因为它是异步的,你不能说任何事情是错误的。如果您想要比猜测更好的答案,我们真的需要一个完整的示例,我们可以将其复制并粘贴到我们的机器上以查看行为。

标签: c# .net multithreading async-await uwp


【解决方案1】:

这是一个很常见的错误。您显示的代码可以同时运行多次。例如,如果将它附加到一个按钮单击事件,用户可以连续单击该按钮十次,从而导致该函数的十个副本几乎同时运行。

在此示例中,它们不会真正同时运行,因为它们与 UI 线程相关联,但它们可以与调度程序重叠,每次它看到 await 语句时从一个实例跳转到下一个实例。


如果您在后台运行它(例如 Thread.Start),那么每个实例都会有自己的线程,并且您确实会同时运行多个副本。

【讨论】:

  • 好点。您的回答,以及 2 分钟前在 a comment 中的相同内容,让我意识到还有另一个相关的细节(现在已编辑到问题中) - b 留下了 true after all迭代。不过谢谢!
猜你喜欢
  • 1970-01-01
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
  • 2011-11-03
  • 2015-01-22
  • 2014-01-08
  • 2010-09-11
  • 1970-01-01
相关资源
最近更新 更多