程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> try-catch-finally 引發的奇怪問題

try-catch-finally 引發的奇怪問題

編輯:C#入門知識

今天,發現我們的一個Windows Service無法正常停止,無奈之下只能殺了進程。   為了找到原因,我在本地進行調試,發現程序裡用到了多線程,而代碼正是卡在了workThread.Abort()語句而無法停止。   為什麼不能Abort? 繼續看線程調用的方法的代碼,發現沒有什麼特殊的代碼,只是在其中用了Thread.Sleep進行長時間等待。   難道是這個引起的? 寫了一個測試程序驗證,    

class Program  
    {  
        private readonly Thread workThread;  
  
        public Program()  
        {  
            workThread = new Thread(DoWork);  
        }  
  
        static void Main(string[] args)  
        {  
            new Program().Work();  
            Console.ReadLine();  
        }  
  
        private void Work()  
        {  
            workThread.Start();  
            Thread.Sleep(1 * 1000);  
  
            Console.WriteLine("aborting");  
            workThread.Abort();  
            Console.WriteLine("aborted");  
        }  
  
        private void DoWork()  
        {  
                Console.WriteLine("started");  
               Thread.Sleep(300 * 1000);  
        }  
    }  
發現可以正常終止。

started
aborting
aborted


再仔細檢查,發現其中一處Thread.Sleep放在了finally塊中,修改測試代碼

class Program
    {
        private readonly Thread workThread;

        public Program()
        {
            workThread = new Thread(DoWork);
        }

        static void Main(string[] args)
        {
            new Program().Work();
            Console.ReadLine();
        }

        private void Work()
        {
            workThread.Start();
            Thread.Sleep(1 * 1000);
            Console.WriteLine("aborting");
            workThread.Abort();

            Console.WriteLine("aborted");
        }

        private void DoWork()
        {
            try
            {
                Console.WriteLine("started");
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                for (int i = 0; i < 3; i++)
                {
                    Console.WriteLine("ThreadState:" + workThread.ThreadState);
                    Thread.Sleep(1000);
                }
            }
        }
    }

 

  輸出:   started ThreadState:Running aborting ThreadState:AbortRequested ThreadState:AbortRequested aborted MSDN是這樣解釋的:   線程不一定會立即中止,或者根本不中止。 如果線程在作為中止過程的一部分被調用的 finally 塊中做非常大量的計算,從而無限期延遲中止操作,則會發生這種情況。   http://msdn.microsoft.com/zh-cn/library/5b50fdsz.aspx 其實追根溯源,問題是出在程序員對try-catch-finally的濫用上,finally塊應該是用來做一些收尾工作,而不是等待操作。   finally 塊用於清除 try 塊中分配的任何資源,以及運行任何即使在發生異常時也必須執行的代碼。   http://msdn.microsoft.com/zh-cn/library/zwc8s4fz%28v=vs.80%29.aspx     找到了原因,解決方案也挺簡單,將Thread.Sleep從finally塊中移除即可。    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved