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


今天,發現我們的一個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.Sleepfinally塊中移除即可

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM