gpt4 book ai didi

c# - 在展开嵌套的 "Dispose"语句时处理 "using"抛出的异常

转载 作者:可可西里 更新时间:2023-11-01 08:33:34 26 4
gpt4 key购买 nike

显然,在使用嵌套的 using 语句时,一些异常可能会丢失。考虑这个简单的控制台应用程序:

using System;

namespace ConsoleApplication
{
public class Throwing: IDisposable
{
int n;

public Throwing(int n)
{
this.n = n;
}

public void Dispose()
{
var e = new ApplicationException(String.Format("Throwing({0})", this.n));
Console.WriteLine("Throw: {0}", e.Message);
throw e;
}
}

class Program
{
static void DoWork()
{
// ...
using (var a = new Throwing(1))
{
// ...
using (var b = new Throwing(2))
{
// ...
using (var c = new Throwing(3))
{
// ...
}
}
}
}

static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
{
// this doesn't get called
Console.WriteLine("UnhandledException:", e.ExceptionObject.ToString());
};

try
{
DoWork();
}
catch (Exception e)
{
// this handles Throwing(1) only
Console.WriteLine("Handle: {0}", e.Message);
}

Console.ReadLine();
}
}
}

Throwing 的每个实例在被处理时都会抛出。 AppDomain.CurrentDomain.UnhandledException 永远不会被调用。

输出:

Throw: Throwing(3)Throw: Throwing(2)Throw: Throwing(1)Handle: Throwing(1)

我希望至少能够记录丢失的 Throwing(2)Throwing(3)我该怎么做,而不是为每个 using 求助于单独的 try/catch(这会破坏 using 的便利性)?

在现实生活中,这些对象通常是我无法控制的类的实例。他们可能会或可能不会抛出,但如果他们这样做,我希望有一个选项来观察此类异常。

这个问题是在我查看 reducing the level of nested using 时出现的.有一个 neat answer建议聚合异常。有趣的是,这与嵌套 using 语句的标准行为有何不同。

[EDITED] 这个问题似乎密切相关: Should you implement IDisposable.Dispose() so that it never throws?

最佳答案

代码分析器对此有警告。 CA1065 ,“不要在意想不到的地方引发异常”。 Dispose() 方法在该列表中。在 Framework Design Guide 第 9.4.1 章中还有一个强烈警告:

AVOID throwing an exception from within Dispose(bool) except under critical situations where the containing process has been corrupted (leaks, inconsistent shared state, etc.).

这是错误的,因为 using 语句在 finally block 中调用了 Dispose()。在 finally block 中引发的异常可能会产生令人不快的副作用,如果在堆栈因异常而展开时调用 finally block ,它会替换一个事件异常。正是您在这里看到的情况。

重现代码:

class Program {
static void Main(string[] args) {
try {
try {
throw new Exception("You won't see this");
}
finally {
throw new Exception("You'll see this");
}
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
Console.ReadLine();
}
}

关于c# - 在展开嵌套的 "Dispose"语句时处理 "using"抛出的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19238521/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com