none
如何設定能讓 try-finally 的 finally 區塊代碼正常執行? RRS feed

  • 問題

  • 環境:Windows 8.1, Visual Studio 2015 Update 1, .NET 4.6.1 Any CPU

    問題:各位好,我嘗試練習以下 msdn 所提供的 try-finally 陳述式網址,

    https://msdn.microsoft.com/zh-tw/library/zwc8s4fz.aspx

            int i = 123;
            string s = "Some string";
            object obj = s;
    
            try
            {
                // Invalid conversion; obj contains a string, not a numeric type.
                i = (int)obj;
    
                // The following statement is not run.
                Console.WriteLine("WriteLine at the end of the try block.");
            }
            finally
            {
                // To run the program in Visual Studio, type CTRL+F5. Then 
                // click Cancel in the error dialog.
                Console.WriteLine("\nExecution of the finally block after an unhandled\n" +
                    "error depends on how the exception unwind operation is triggered.");
                Console.WriteLine("i = {0}", i);
            }

    我將上述代碼貼到新建立的Console程式,環境如內文第一行,

    執行不偵錯後,得到的結果為

    會出現上圖結果,請問我要如何設定才能正確讓 finally 也能執行?

    2016年5月3日 上午 07:19

解答

  • 請你打開命令提示字元,然後再跑你的程式,你應該會發現在你關掉那個 exception 提示後,finally 的程式會被執行才對。

    這是正常行為。

    當然要吃掉那個 exception 提示,你就必須實作 catch。


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    • 已標示為解答 503 2016年5月3日 下午 04:43
    2016年5月3日 上午 08:21
    版主
  • 你沒有catch exception ,所以結果就是直接原封不動引發該exception應有的行為表現出來
    等你把exception原本的行為做下一步處理(也就是小朱說的),才會做finally
    正常來說exception應該要被適當的補抓後做處理,也就是實作catch

    微軟免費線上課程

    HTML5 & JavaScript程式開發實戰(MyBook)

    開發ASP.NET您要瞭解的基楚

    http://www.dotblogs.com.tw/ian (MyBlog)

    • 已標示為解答 503 2016年5月3日 下午 04:43
    2016年5月3日 上午 08:26

所有回覆

  • 你的catch 跑去哪裡了?

    int i = 123;
                string s = "Some string";
                object obj = s;
                try
                {
                    // Invalid conversion; obj contains a string, not a numeric type.
                    i = (int)obj;
    
                    // The following statement is not run.
                    Console.WriteLine("WriteLine at the end of the try block.");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error:"+ex.ToString());
                }
                finally
                {
                    // To run the program in Visual Studio, type CTRL+F5. Then 
                    // click Cancel in the error dialog.
                    Console.WriteLine("\nExecution of the finally block after an unhandled\n" +
                        "error depends on how the exception unwind operation is triggered.");
                    Console.WriteLine("i = {0}", i);
                }


    微軟免費線上課程

    HTML5 & JavaScript程式開發實戰(MyBook)

    開發ASP.NET您要瞭解的基楚

    http://www.dotblogs.com.tw/ian (MyBlog)

    2016年5月3日 上午 07:44
  • Hi No.18,

    我是按照 try-finally (C# 參考) 

    https://msdn.microsoft.com/zh-tw/library/zwc8s4fz.aspx

    的範例1所練習的,在 msdn 上的範例顯示輸出為

        // Output:
        // Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
        //
        // Execution of the finally block after an unhandled
        // error depends on how the exception unwind operation is triggered.
        // i = 123
    但因我得不到相同結果,想請問原因是什麼,感謝。

    2016年5月3日 上午 07:48
  • 請你打開命令提示字元,然後再跑你的程式,你應該會發現在你關掉那個 exception 提示後,finally 的程式會被執行才對。

    這是正常行為。

    當然要吃掉那個 exception 提示,你就必須實作 catch。


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    • 已標示為解答 503 2016年5月3日 下午 04:43
    2016年5月3日 上午 08:21
    版主
  • 你沒有catch exception ,所以結果就是直接原封不動引發該exception應有的行為表現出來
    等你把exception原本的行為做下一步處理(也就是小朱說的),才會做finally
    正常來說exception應該要被適當的補抓後做處理,也就是實作catch

    微軟免費線上課程

    HTML5 & JavaScript程式開發實戰(MyBook)

    開發ASP.NET您要瞭解的基楚

    http://www.dotblogs.com.tw/ian (MyBlog)

    • 已標示為解答 503 2016年5月3日 下午 04:43
    2016年5月3日 上午 08:26
  • Hi 小朱,

    我使用命令提示字元,切換到該執行檔目錄,分別測試 Debug 與 Release,但執行後,並按下關閉程式按鈕後,一樣沒有執行 finally 區塊的代碼,請問是為什麼?

    2016年5月3日 上午 08:41
  • Hi No.18,

    感謝回覆,因為原本問題是問 try-finally,所以Catch的部分我沒有實作是因為我想測試只有try-finally這樣的情況,

    想假設是否若呼叫只有實作try-finally的Method,呼叫者沒有 try-catch時,是否能正常執行finally部分。

    2016年5月3日 上午 08:45
  • 我試和你相同的程式碼,finally 可以正常執行。

    不過看你最後的回應,你的程式碼應該不是長那樣,所以又要玩猜猜看了。


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure


    2016年5月3日 下午 03:43
    版主
  • 我另外試了你所說的情況,一樣沒問題。

    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                Test();
            }
    
            static void Test()
            {
                int i = 123;
                string s = "Some string";
                object obj = s;
    
                try
                {
                    // Invalid conversion; obj contains a string, not a numeric type.
                    i = (int)obj;
    
                    // The following statement is not run.
                    Console.WriteLine("WriteLine at the end of the try block.");
                }
                finally
                {
                    // To run the program in Visual Studio, type CTRL+F5. Then 
                    // click Cancel in the error dialog.
                    Console.WriteLine("\nExecution of the finally block after an unhandled\n" +
                        "error depends on how the exception unwind operation is triggered.");
                    Console.WriteLine("i = {0}", i);
                }
            }
        }
    }
    


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    2016年5月3日 下午 03:47
    版主
  • 我另外試了你所說的情況,一樣沒問題。

    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                Test();
            }
    
            static void Test()
            {
                int i = 123;
                string s = "Some string";
                object obj = s;
    
                try
                {
                    // Invalid conversion; obj contains a string, not a numeric type.
                    i = (int)obj;
    
                    // The following statement is not run.
                    Console.WriteLine("WriteLine at the end of the try block.");
                }
                finally
                {
                    // To run the program in Visual Studio, type CTRL+F5. Then 
                    // click Cancel in the error dialog.
                    Console.WriteLine("\nExecution of the finally block after an unhandled\n" +
                        "error depends on how the exception unwind operation is triggered.");
                    Console.WriteLine("i = {0}", i);
                }
            }
        }
    }


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    另一種情況是我假設,但我還沒開始寫,因為第一個範例我就遇到問題了,

    我真的是跟原範例一樣的! 我在家裡嘗試也還是不行:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace try_finallyConsoleSmaple
    {
        class Program
        {
            static void Main(string[] args)
            {
                int i = 123;
                string s = "Some string";
                object obj = s;
    
                try
                {
                    // Invalid conversion; obj contains a string, not a numeric type.
                    i = (int)obj;
    
                    // The following statement is not run.
                    Console.WriteLine("WriteLine at the end of the try block.");
                }
                finally
                {
                    // To run the program in Visual Studio, type CTRL+F5. Then 
                    // click Cancel in the error dialog.
                    Console.WriteLine("\nExecution of the finally block after an unhandled\n" +
                        "error depends on how the exception unwind operation is triggered.");
                    Console.WriteLine("i = {0}", i);
                }
            }
        }
    }
    

    這是我實際測試的代碼,感謝~

    2016年5月3日 下午 04:32
  • 更正,我在家裡測試可以= =
    2016年5月3日 下午 04:34
  • 我明白了,為什麼一下可以一下不行,

    在這個畫面的時候,馬上關閉這個視窗,就能正常顯示 finally 區塊代碼

    但是當他變成這樣的時候,

    按什麼都不會在執行 finally 區塊代碼了!

    2016年5月3日 下午 04:38
  • 不確定是不是 .NET 的 bug,不過我試就算出現後面的畫面,它還是會跑 finally。

    我是在 .NET 4.6.1, VS 2015 Update 2 上試的。


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    2016年5月4日 上午 02:20
    版主
  • 我上面貼試成功的環境,也是 .NET 4.6.1, VS 2015 Update 2, Windows 10
    2016年5月4日 下午 02:47