一個經典的例子:
問題:
都說Invoke是同步的,BeginInvoke是異步的,但為何用BeginInvoke做耗時操作依然會卡死UI?
http://www.cnblogs.com/blosaa/archive/2013/05/30/3107381.html
小結:
BeginInvoke的異步是指相對於調用BeginInvoke的線程異步,而不是相對於UI線程異步。所以在UI線程調用BeginInvoke依然會卡死UI。
解決辦法是開一個子線程,耗時操作在該子線程中完成,完成后在子線程中調用BeginInvoke交由UI線程更新界面,而不是在UI線程中調用BeginInvoke。
注意,記好Control的Invoke和BeginInvoke都執行在主線程即UI線程上!(這是Winform的情況,WPF中交由Control所關聯的Dispatcher來處理,Control身上沒有Invoke和BeginInvoke)
測試發現,C#的主線程(UI線程)默認是未命名的,Name屬性為null。想要知道獲得的線程是否為主線程,可以在Visual Studio的【線程】窗口中看到,如下圖。既然不知道線程的Name,那么還可以通過線程的托管ID來知曉。

Thread objThread = new Thread(new ThreadStart(delegate { Console.WriteLine("當前線程ID = " + Thread.CurrentThread.ManagedThreadId); // 是子線程 Console.WriteLine("當前線程ID = " + Application.Current.Dispatcher.Thread.ManagedThreadId); // 是UI線程 }));
關於使用ManualResetEvent使線程阻塞與繼續:
