【问题标题】:Point of try catch finally blocks?try catch 的点最终阻塞?
【发布时间】:2025-12-17 21:10:01
【问题描述】:

和finally有什么区别

void ReadFile(int index)
{
    // To run this code, substitute a valid path from your local machine
    string path = @"c:\users\public\test.txt";
    System.IO.StreamReader file = new System.IO.StreamReader(path);
    char[] buffer = new char[10];
    try
    {
        file.ReadBlock(buffer, index, buffer.Length);
    }
    catch (System.IO.IOException e)
    {
        Console.WriteLine("Error reading from {0}. 
           Message = {1}", path, e.Message);
    }
    finally
    {
        if (file != null)
        {
            file.Close();
        }
    }
    // Do something with buffer...
}

不使用它?

void ReadFile(int index)
{
    // To run this code, substitute a valid path from your local machine
    string path = @"c:\users\public\test.txt";
    System.IO.StreamReader file = new System.IO.StreamReader(path);
    char[] buffer = new char[10];
    try
    {
        file.ReadBlock(buffer, index, buffer.Length);
    }
    catch (System.IO.IOException e)
    {
        Console.WriteLine("Error reading from {0}. 
            Message = {1}", path, e.Message);
    }

    if (file != null)
    {
        file.Close();
    }

    // Do something with buffer...
}

【问题讨论】:

  • catch 块可能会重新抛出错误,引发新错误等,这将绕过 finally 的关闭。见这里 - *.com/questions/50618/…
  • 我知道其他人会比我更快地输入答案,但您是否考虑过导致 IOException 并亲自查看差异?

标签: c# try-catch try-catch-finally


【解决方案1】:

无论是否抛出异常或抛出什么异常,前面的示例都将运行file.Close()

只有在没有抛出异常或抛出 System.IO.IOException 时,后者才会运行。

【讨论】:

  • 是的,我当时不能,直到现在才上场。
【解决方案2】:

不同之处在于,如果您不使用 finally 并引发除 IOException 以外的异常,您的应用程序将泄漏文件句柄,因为永远无法到达 .Close 行。

我个人在处理流等一次性资源时总是使用using 块:

try
{
    using (var reader = File.OpenText(@"c:\users\public\test.txt"))
    {
        char[] buffer = new char[10];
        reader.ReadBlock(buffer, index, buffer.Length);
         // Do something with buffer...
    }
}
catch (IOException ex)
{
    Console.WriteLine("Error reading from {0}. Message = {1}", path, e.Message);
}

这样我就不必担心如何妥善处理它们。 try/finally 的东西由编译器处理,我可以专注于逻辑。

【讨论】:

  • 是的,我只是复制并粘贴了一个示例,如果我没有指定 IOExceptions 怎么办?
【解决方案3】:

您的 catch 块本身可能会引发异常(考虑path 为空引用的情况)。或者try块中抛出的异常不是System.IO.IOException,所以不处理。除非使用finally,否则文件句柄在这两种情况下都不会关闭。

【讨论】:

    【解决方案4】:

    在你的情况下,什么都没有。如果你让异常从 catch 块中抛出,那么 finally 部分会运行,但其他变体不会。

    【讨论】: