c#在新執行緒建立窗體卡住問題
阿新 • • 發佈:2018-12-26
問題描述
最近遇到一個問題,在new 一個form 後發現新建立的窗體卡住了,裡面的控制元件刷不出來。百度後發現原來是在一個新的執行緒裡建立了窗體,而新執行緒是一直阻塞的,導致窗體刷不出來。
解決辦法
參考網上的解決方法,在主UI執行緒裡寫了建立窗體的方法,然後在新執行緒裡呼叫。為了更好的實現封裝性(新執行緒所在的類不直接訪問主執行緒所在的類),在主視窗新建一個靜態的委託,以便呼叫:
public static Action<string> OnShowForm;
在主窗體中把委託和建立窗體的方法名關聯起來
public ClientMainForm() { InitializeComponent(); OnShowRespondRequestForm += ShowForm; }
在建立窗體的方法中,注意要呼叫主UI執行緒的Invoke函式來實現建立窗體,為了程式碼精煉,使用了匿名委託和匿名方法
public void ShowForm(string str) { //在監聽執行緒裡呼叫這個委託方法 //這裡用Invoke表示通過主UI執行緒建立窗體 //括號裡面傳入一個匿名的無參Action委託 //委託裡傳入一個匿名無參方法 this.Invoke(new Action(delegate(){ MessageForm fo = new MessageForm (str); fo.Show(); })); }
或者換一種寫法,利用Invoke來傳遞引數
public void ShowForm(string str) { //通過Invoke傳遞兩個引數 //匿名Action接受兩個引數 //Action括號裡的匿名方法接受兩個引數 this.Invoke(new Action<string>(delegate(string ss){ MessageForm fo = new MessageForm (ss); fo.Show(); }), new object[]{str}); }
這樣寫的原因是Invoke函式裡面接受的是一個委託,不能直接寫入匿名方法,所以用.net內建的Action委託封裝了一下匿名方法,再傳入函式。