Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 最后阻塞try/catch不工作?_C#_Oop_Exception_Exception Handling - Fatal编程技术网

C# 最后阻塞try/catch不工作?

C# 最后阻塞try/catch不工作?,c#,oop,exception,exception-handling,C#,Oop,Exception,Exception Handling,好的,据我所知,try/catch块尝试一个操作,catch块捕获异常。越是特定的异常出现在顶部,越是通用的异常出现在一系列catch块的底部。在下面的代码中,我实现了try/catch,一切正常 据我所知,finally块总是执行。有些人认为最终阻塞没有任何意义,因为如果有异常或没有异常,最后一个catch块之后的代码无论如何都会被执行 然而,反对这一点的理由是,如果catch块中抛出了异常,则没有后续的catch块来捕获该异常。因此,通过将资源清理代码放在finally块中,可以确保在cat

好的,据我所知,try/catch块尝试一个操作,catch块捕获异常。越是特定的异常出现在顶部,越是通用的异常出现在一系列catch块的底部。在下面的代码中,我实现了try/catch,一切正常

据我所知,finally块总是执行。有些人认为最终阻塞没有任何意义,因为如果有异常或没有异常,最后一个catch块之后的代码无论如何都会被执行

然而,反对这一点的理由是,如果catch块中抛出了异常,则没有后续的catch块来捕获该异常。因此,通过将资源清理代码放在finally块中,可以确保在catch块中引发异常时释放资源

这就是为什么下面的代码让我感到困惑。我在第一个catch块中抛出一个异常,而finally块永远不会执行。为什么?

*请注意,在创建myStreamReader时确实会引发异常,因为该文件实际上名为generic.txt,并且拼写错误,目的是为了引发初始异常

StreamReader myStreamReader = null;

try
{
   myStreamReader = new StreamReader("c:\\genneric.txt");   
   Console.WriteLine(myStreadReader.ReadToEnd());       
}

catch(FileNotFoundException Error)
{
   Console.WriteLine(Error.Message);
   Console.WriteLine(); 
   throw new Exception();
}

catch(Exception Error)
{
   Console.WriteLine(Error.Message);
   Console.WriteLine();
}

finally
{

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

  Console.WriteLine("Closed the StreamReader.");
}
视频:

这段代码的问题源于这段视频,时间是27:20:


guy直接声明catch块中发生的异常不会阻止finally块执行。我发现它确实如此。

使用
抛出
并尝试此操作。当您抛出新异常时,实际异常将丢失。但是当您使用just
throw
时,它将抛出实际的异常,即
FileNotFoundException

StreamReader myStreamReader = null;

try
{
   myStreamReader = new StreamReader("c:\\genneric.txt");   
   Console.WriteLine(myStreadReader.ReadToEnd());       
}

catch(FileNotFoundException Error)
{
   Console.WriteLine(Error.Message);
   Console.WriteLine(); 
   throw;
}

catch(Exception Error)
{
   Console.WriteLine(Error.Message);
   Console.WriteLine();
}

finally
{
  Console.WriteLine("Closing the StreamReader.");
  try{
    if(myStreamReader != null)
   {
      myStreamReader.Close();
   }
  } catch(Exception e) {  Console.WriteLine(e.ToString())  };
}


}

假设找不到该文件,它将首先捕获
FileNotFoundException

catch(FileNotFoundException error)
{
    Console.WriteLine(error.Message);
    Console.WriteLine(); 
    throw new Exception();
}
这将向控制台写入一条消息,然后抛出一个新的
异常。但是,此异常未经处理,将停止执行。如果从
Catch
块中抛出异常,则任何后续块都不会捕获该异常


解决方案是适当地处理异常,而不是抛出新异常。如果找不到文件,则对其采取行动,例如让用户选择另一个文件、创建文件等。

您的理解不正确。看

通过使用finally块,您可以清理所有被删除的资源 在try块中分配,即使出现异常,也可以运行代码 在try块中发生。通常,finally块的语句 当控件留下try语句时运行。控制权的转移可以 由于正常执行、中断执行而发生, continue、goto或return语句,或异常的传播 在try语句之外

所以,如果从try块返回实例,那么finally不会执行,但如果从catch块抛出,则不会执行

但是,如果未处理异常,则finally块的执行 取决于异常展开操作的触发方式。那个 反过来,这取决于计算机的设置方式


如果新异常完全未处理,则整个过程将被中断,
finally
块将永远无法运行

如果在更高级别上有其他异常处理程序,或者安装了未处理的异常处理程序,
finally
块将运行


此示例显示“已关闭StreamReader”:


未经处理的异常处理程序可以在事件中注册。

不要听这些人告诉你没有目的,他们很可能做得不正确。通常也建议只使用您可以处理的异常。如果发生未经处理的异常,finally也将运行。我同意你的第一句话。然而,在本例中,finally块似乎没有运行。我从未看到文本“closedthestreamreader”。所以很明显,第一个catch块中抛出了一个异常,但是finally块没有执行。检查这个@PrasanthVJ Great链接,但是顶部选择的答案(+22)似乎表明finally块确实运行。我不认为这是事实。投掷和投掷有什么区别;和throw new Exception()?此外,在finally语句中不需要try/catch块,因为在对myStreamReader执行null测试时不可能出现错误,因为myStreamReader在第一个try块之前设置为null。如果它从未被创建(创建时出错),它将保持为空。@user330843我同意,我确实在最后清理了,我只是有一个捕获,只有一个日志记录,有时甚至是空的,这样如果我有多个清理活动,就不会出问题。好的,但在这种情况下它确实是多余的。空检查不可能出错。如果从
catch
块抛出,则会执行空检查。。。只要异常在别处被捕获。但不管怎样+1,你在下面的视频中引用了我将要引用的规范的相同部分。27:20标记:他声明,如果在catch blockWell中抛出异常,则始终执行finally blocks,然后他声明错误。从Catch块抛出的异常是未处理的,除非它是从嵌套的Try块抛出并由嵌套的Catch块无限处理。非常好,谢谢。这似乎是事实,我确实开始意识到他错了。我也不认为我误解了他,因为他几乎直接在视频中陈述了这一点。太好了,谢谢。那么,处理catch块中抛出的异常的最佳方法是什么?@user3308043-这在很大程度上取决于您是否可以做一些有用的事情来允许程序继续。这是非常具体的情况,没有通用的建议提供。考虑到您的代码示例只是一个玩具(而且也是一个坏的,因为它有输入错误并且无法编译),很难针对您的情况提供任何具体的建议。如果什么都没有
    static void Main()
    {
        try
        {
            StreamReader myStreamReader = null;

            try
            {
                myStreamReader = new StreamReader("c:\\genneric.txt");
                Console.WriteLine(myStreamReader.ReadToEnd());
            }

            catch (FileNotFoundException Error)
            {
                Console.WriteLine(Error.Message);
                Console.WriteLine();
                throw new Exception();
            }

            catch (Exception Error)
            {
                Console.WriteLine(Error.Message);
                Console.WriteLine();
            }

            finally
            {

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

                Console.WriteLine("Closed the StreamReader.");
            }
        }
        catch
        {

        }
        Console.WriteLine("Done");
        Console.ReadLine();
    }