这个问题出现,因为在.NET 4.0曾任职代码在.NET 4.5中未处理的异常失败,因为尝试/ finallys的部分。 如果您想详细信息,请仔细阅读在微软连接 。 我用它作为基地在这个例子中,所以它可能是有益的参考。
代码
对于谁选择不阅读这背后的问题细节的人来说,这里是一个非常快看看那里发生这种情况的条件:
using(var ms = new MemoryStream(encryptedData))
using(var cryptoStream = new CryptoStream(encryptedData, decryptor, CryptoStreamMode.Read))
using(var sr = new StreamReader(cryptoStream))
这个问题是有异常从抛出Dispose
CryptoStream的方法(因为它们是用一个语句中,这些异常发生从两个不同的finally块抛出)。 当cryptoStream.Dispose()
是由被叫StreamReader
,该CryptographicException
异常。 第二次cryptoStream.Dispose()
被调用时,在其使用的语句,它抛出一个ArgumentNullException
下面的代码去除大部分从上面提供的链接不必要的代码,并使用语句解开进入试/ finallys清楚地表明,他们是在finally块被抛出。
using System;
using System.Security.Cryptography;
namespace Sandbox
{
public class Program
{
public static void Main(string[] args)
{
try
{
try
{
try
{
Console.WriteLine("Propagate, my children");
}
finally
{
// F1
Console.WriteLine("Throwing CryptographicExecption");
throw new CryptographicException();
}
}
finally
{
// F2
Console.WriteLine("Throwing ArgumentException");
throw new ArgumentException();
}
}
catch (ArgumentException)
{
// C1
Console.WriteLine("Caught ArgumentException");
}
// Same behavior if this was in an enclosing try/catch
catch (CryptographicException)
{
// C2
Console.WriteLine("Caught CryptographicException");
}
Console.WriteLine("Made it out of the exception minefield");
}
}}
注:尝试/终于对应于从引用的代码语句中使用扩展。
输出:
Propagate, my children Throwing CryptographicExecption Throwing ArgumentException Caught ArgumentException Press any key to continue . . .
它不会出现该CryptographicException
是不断执行catch块。 然而,除去catch块会导致异常终止运行系统。
有一点了解更多信息
编辑:这是更新到规范的最新版本。 我碰巧抓住过MSDN的一个较老了措辞。 Lost
于已更新terminated
。
潜水到C#规范,部分8.9.5和8.10讨论异常行为:
- 当一个异常被抛出,包括从finally块内,控制在一个封闭try语句转移到第一catch子句。 直到一个合适的被发现这样下去了try语句。
- 如果异常是最后块的执行期间抛出,和一个异常已经被传播, 该异常终止
“终止”使得它似乎是第一个异常将永远被第二抛出的异常被隐藏,但似乎是发生了什么不。
我敢肯定,问题是在这里的某个地方
在大多数情况下,人们很容易想象一下运行时正在做什么。 该代码执行到所述第一最后块( F1
,其中将引发异常)。 作为异常传播时,所述第二异常是从所述第二抛出最后块( F2
)。
根据规范,在CryptographicException
从抛出F1
现在终止,并且运行时寻找的处理程序ArgumentException
。 运行时查找处理程序,并执行在用于捕捉块中的代码ArgumentException
( C1
)。
这是它得到云里雾里:规范说,第一个异常将被终止。 然而,如果第二个catch块( C2
)从代码,除去的CryptographicException
该假想丢失,是现在终止程序未处理的异常。 与C2
存在,该代码将不会从一个未处理的异常终止,所以在表面上看来可以处理异常,但永远不会执行该块中的实际的异常处理代码。
问题
这些问题基本上是相同的,但重新措辞的特异性。
它是如何使
CryptographicException
会因终止于ArgumentException
从封闭抛出finally块,去掉了异常catch (CryptographicException)
块会导致异常未处理去和终止运行系统?由于运行时似乎处理
CryptographicException
当catch (CryptographicException)
块存在,为什么不执行块内的代码?
额外信息编辑
我仍然在寻找到这样做的实际行为,而许多问题的答案已经在至少回答以上问题的部分特别有帮助。
另一个奇怪的行为,当您运行与该代码发生catch (CryptographicException)
注释掉块,是.NET 4.5和.NET 3.5的区别。 .NET 4.5将引发CryptographicException
和终止应用程序。 .NET 3.5,但是,似乎根据C#规范在异常表现得更。
Propagate, my children Throwing CryptographicExecption Unhandled Exception: System.Security.Cryptography.CryptographicException [...] ram.cs:line 23 Throwing ArgumentException Caught ArgumentException Made it out of the exception minefield
在.NET 3.5中,我看到了我在读规范。 唯一的例外变为“丢失”,或者“终止”,因为这永远需要被抓到的唯一的事情就是ArgumentException
。 正因为如此,程序可以继续执行。 我只有.NET 4.5我的机器上,我不知道如果这种情况发生在.NET 4.0中?