【问题标题】:Where do I put try/catch with "using" statement? [duplicate]我在哪里放置带有“使用”语句的 try/catch? [复制]
【发布时间】:2011-09-02 23:12:37
【问题描述】:

可能重复:
try/catch + using, right syntax

我想try/catch以下:

//write to file
using (StreamWriter sw = File.AppendText(filePath))
{
    sw.WriteLine(message);
}

我是将try/catch 块放在using 语句中,还是在它周围,或两者兼而有之?

【问题讨论】:

  • 您是否担心在 WriteLine 调用、AppendText 调用中捕获异常?
  • 这取决于您是否可以处理 using 块内的异常,或者异常是否会使整个 using 块变得多余
  • @jglouie 我想两者兼得。
  • 我认为这个问题不应该被关闭,因为另一个问题的公认答案是可怕的!
  • @Jeffrey:同意另一个接受的答案。您应该在该问题下重新发布您的。

标签: c# try-catch using-statement


【解决方案1】:

如果你的 catch 语句需要访问 using 语句中声明的变量,那么 inside 是你唯一的选择。

如果你的 catch 语句需要在 using 中引用的对象在被释放之前,那么 inside 是你唯一的选择。

如果您的 catch 语句执行一个持续时间未知的操作,例如向用户显示一条消息,并且您希望在此之前处置您的资源,那么外部是您的最佳选择。

每当我遇到与此类似的场景时,try-catch 块通常使用不同的方法,在调用堆栈中从 using 开始。一个方法知道如何处理它内部发生的异常是不典型的。

所以我的一般建议是在外面——在外面。

private void saveButton_Click(object sender, EventArgs args)
{
    try
    {
        SaveFile(myFile); // The using statement will appear somewhere in here.
    }
    catch (IOException ex)
    {
        MessageBox.Show(ex.Message);
    }
}

【讨论】:

  • +1 for 'outside—way outside'
【解决方案2】:

我想这是首选方式:

try
{
    using (StreamWriter sw = File.AppendText(filePath))
    {
        sw.WriteLine(message);
    }
}
catch(Exception ex)
{
   // Handle exception
}

【讨论】:

    【解决方案3】:

    如果你仍然需要一个 try/catch 块,那么 using 语句不会给你带来太多好处。放弃它,改为这样做:

    StreamWriter sw = null;
    try
    {
        sw = File.AppendText(filePath);
        sw.WriteLine(message);
    }
    catch(Exception)
    {
    }
    finally
    {
        if (sw != null)
            sw.Dispose();
    }
    

    【讨论】:

    • 非常可怕的代码。没有理由放弃 using 块的便利性(可读性、简单性)。
    • @Henk:你确实意识到这是一个完全主观的意见?我碰巧认为 finally 块是可读的、方便的和简单的。 using 语句在有意义时是很好的语法糖,但在这种情况下它没有意义。
    • 更正:using 语句没有告诉 GC。它(由 C# 编译器)展开为包含对对象的 IDisposable.Dispose() 方法实现的调用的 try/finally(在 IL 中)。它确实作为向开发人员指示应该发生处置的指示符,类似于在 finally 块中显式调用 Dispose 指示处置应该发生的方式。
    • 人们不太可能忘记在 finally 块中调用 dispose,而不是忘记将对象包装在 using 块中(就像许多开发人员所做的那样)。来自 MSDN “finally 块对于清理任何资源都很有用......”我认为我们已经彻底击败了这个块。
    • @hemp 在整个演讲中都非常正确。虽然我仍然鼓励using 甚至只是为了一致性而在 try/catch 内部,但如果程序员不知道他们应该处理一个对象,那么这两种模式都无关紧要。这纯粹涉及偏好,根据定义,偏好是主观的。我确实喜欢把它放在finally 块中的想法,但我不会仅仅因为我害怕混淆其他可能不理解的程序员。
    猜你喜欢
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 2015-02-27
    • 2010-10-06
    • 2016-07-02
    • 2015-02-08
    • 2012-11-29
    • 2018-08-22
    相关资源
    最近更新 更多