首先要承認這個標題有那麼一丁點標題黨,但這又不是完全的標題黨。使用“正確”的調試方法的確可以把 VS 給搞死結了。至於 VS 被死結了算不算 Bug,這個問題有待於商榷。不想吐槽,先看看怎麼用“正確”的方法把 VS 搞死結。
首先要建立一個控制台項目,完整的複製下列代碼:
using System.Threading;namespace DeadlockVS{ class Program { static object _obj = new object(); static void Main(string[] args) { Thread.CurrentThread.Name = "Main Thread"; ThreadStart ts = () => { while (true) { lock (_obj) Thread.Sleep(100); Thread.Sleep(1); } }; for (int i = 0; i < 2; i++) new Thread(ts).Start(); Thread.Sleep(1000); ts(); } static int Get() { lock (_obj) return 1; } }}
然後在正確的位置插上正確的斷點:
然後在即時視窗裡面輸入:Get()
現在你的 VS 有99.99%的機率會到達一種“死結”狀態(如果沒有被死結,恭喜你,你現在就可以去買雙色球,記得中獎了分大家一點)。IDE 在等待寄主進程返回結果,而寄主進程又需要等待其中的某一個線程釋放鎖,又因為處在調試狀態,寄主進程沒辦法繼續執行下一步代碼,也就無法釋放鎖,最終導致了一個死結的存在。雖然是死結,但是 VS 的 UI 並沒有被鎖死,所以我們現在唯一能做的事情就是結束調試。
現在實驗結束,大家來討論下這算不算是 VS 的一個 Bug?
正方觀點:
- 會影響正常調試,當然算 Bug
- 只要導致程式非正常終止的都算 Bug
反方觀點:
- 是你自己調試方法不正確,不能怪 VS
- BUG本身是錯誤,是不按正常的理解執行,不是說死結就是有BUG
怎麼才能解決這一“Bug”?
- 從程式員自身角度考慮,只有增加自身編碼能力和調試能力
- 從 VS 健壯角度考慮,可以使用沙箱模式,並檢測到在執行一定時間還未得出結果後,主動退出。
再看看維基百科是怎麼定義 Bug 的:程式錯誤(英語:Bug),在程式設計中的術語,是指在軟體運行中因為程式本身有錯誤而造成的功能不正常、死機、資料丟失、非正常中斷等現象。http://zh.wikipedia.org/wiki/%E7%A8%8B%E5%BA%8F%E9%94%99%E8%AF%AF
關於類似問題的探討,還有另外一篇博文《一個WPF和SL的嚴重BUG,能導致任何的寄主程式崩潰》。