gpt4 book ai didi

c# - C# 的 using 语句中止安全吗?

转载 作者:IT王子 更新时间:2023-10-29 04:16:37 26 4
gpt4 key购买 nike

我刚刚读完“C# 4.0 in a Nutshell”(O'Reilly),我认为对于愿意切换到 C# 的程序员来说这是一本很棒的书,但它让我感到疑惑。我的问题是 using 语句的定义。根据该书(第 138 页),

using (StreamReader reader = File.OpenText("file.txt")) {
...
}

恰好等同于:

StreamReader reader = File.OpenText("file.txt");
try {
...
} finally {
if (reader != null)
((IDisposable)reader).Dispose();
}

然而,假设这是真的,并且这段代码是在一个单独的线程中执行的。这个线程现在被 thread.Abort() 中止,所以一个 ThreadAbortException 被抛出并且假设线程刚好在初始化 reader 之后和进入 try 之前。 .finally 子句。这将意味着读者没有被处置!

一个可能的解决方案是这样编码:

StreamReader reader = null;
try {
reader = File.OpenText("file.txt");
...
} finally {
if (reader != null)
((IDisposable)reader).Dispose();
}

这将是中止安全的。

现在回答我的问题:

  1. 这本书的作者是否正确,using 语句不是中止安全的,或者他们错了,它的行为就像我的第二个解决方案?
  2. 如果 using 等同于第一个变体(不是中止安全的),为什么它会在 finally 中检查 null?<
  3. 根据该书(第 856 页),ThreadAbortException 可以在托管代码中的任何位置抛出。但也许有异常(exception),毕竟第一个变体是中止安全的?

编辑:我知道使用thread.Abort() 不是好的做法。我的兴趣纯粹是理论上的:using 语句的行为如何准确地

最佳答案

本书的配套网站有更多关于中止线程的信息 here .

总之,第一个翻译是正确的(看IL就知道了)。

第二个问题的答案是,在某些情况下,变量可以合法地为 null。例如,GetFoo() 可能会在此处返回 null,您不希望在隐式 finally block 中抛出 NullReferenceException:

using (var x = GetFoo())
{
...
}

要回答您的第三个问题,使 Abort 安全的唯一方法(如果您正在调用框架代码)是之后拆除 AppDomain。在许多情况下,这实际上是一个实用的解决方案(这正是 LINQPad 在您取消正在运行的查询时所做的事情)。

关于c# - C# 的 using 语句中止安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3923457/

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