1. 程式人生 > >c#在新執行緒建立窗體卡住問題

c#在新執行緒建立窗體卡住問題

問題描述

最近遇到一個問題,在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委託封裝了一下匿名方法,再傳入函式。