简体   繁体   English

由于“尝试”中的异步,“最终”未执行?

[英]“finally” not executed because of Async in “try”?

I have a bool ( b ) which appears only twice in my code (besides its declaration): 我有一个布尔( b )在代码中仅出现两次(除其声明外):

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

yet sometimes the try block is started with b being true (- before b = true ) which should never be happening because the declaration leaves it false , as does the previous finally . 但是有时try块的开头btrue (- b = true 之前 ),这永远不会发生,因为声明将其设为false ,就像前面的finally At some point, this code is executed in a loop, which in some cases is iterating quickly and SomeAsync() is trying to use too much memory. 在某些时候,此代码是在循环中执行的,在某些情况下,该循环正在快速迭代,并且SomeAsync()尝试使用过多的内存。 I assume that is throwing an exception of a type that can "break" a finally . 我认为这引发了一个异常,该异常可以 “破坏” finally ( b is always false as expected when there's only a normal amount of data for SomeAsync() to process.) (当SomeAsync()仅需要处理正常数量的数据时, b总是如预期那样为false 。)

I've tried verifying what Visual Studio shows me with Debug.WriteLine() both after the try and after the finally , and also by appending to a string a different character in those places, but then the finally was executed. 我试过验证什么Visual Studio中显示我Debug.WriteLine()后都try后的finally ,也可以通过追加到一个字符串不同的字符在那些地方,但随后finally 执行。 So I assume that the slow delay was enough to prevent the exception. 因此,我认为缓慢的延迟足以防止异常发生。

Is this really possible? 这真的有可能吗? (Any ideas on how to verify it or fix it so that the finally always runs?) (关于如何验证或修复它以便最终运行的任何想法?)

(finally blocks can fail - cases: Conditions when finally does not execute in a .net try..finally block ) (最终块可能会失败-情况: 最终无法在.net try..finally块中执行的条件

EDIT 编辑

A good point was raised in a comment and an answer - that this code might be executed several times concurrently during the awaits . 在注释和答案中提出了一个很好的观点-该代码可能在awaits期间同时执行多次。 Unfortunately, there's another detail (that those answers made me aware is pertinent) - after all iterations - the state is that b is true . 不幸的是,还有另一个细节(这些答案使我知道是相关的)-在所有迭代之后-状态为btrue That is not explained by concurrency. 并发不能解释一点。 I have also added an if (b) return; 我还添加了一个if (b) return; before the try block (to avoid calling the Async while the previous is running). try块之前(以避免在运行前一个块时调用Async )。 Still getting left with a true b after all iterations are done. 在所有迭代完成之后,仍然剩下true b

This is a pretty common mistake. 这是一个很常见的错误。 The code you showed can be run multiple times concurrently. 您显示的代码可以同时运行多次。 For example, it you attach it to a button click event, the user can click the button ten times in a row, causing ten copies of the function to run at nearly the same time. 例如,将它附加到按钮单击事件,用户可以连续单击按钮十次,从而使该函数的十个副本几乎同时运行。

In this example they won't literally run at the same time, being ties to the UI thread, but they can overlap with the scheduler jumping from one instance to the next every time it sees an await statement. 在此示例中,它们实际上并不会同时运行,因为它们与UI线程相关联,但是它们会与调度程序重叠,每次看到await语句时,调度程序就会从一个实例跳转到下一个实例。


If you are running this in the background (eg Thread.Start) then each instance will get its own thread and you really will have multiple copies running at the same time. 如果在后台运行该线程(例如Thread.Start),则每个实例将获得其自己的线程,并且实际上您将同时运行多个副本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM