C#在新线程创建窗体卡住问题

问题描述
最近遇到一个问题,在new 一个form 后发现新创建的窗体卡住了,里面的控件刷不出来。百度后发现原来是在一个新的线程里创建了窗体,而新线程是一直阻塞的,导致窗体刷不出来。

解决办法
参考网上的解决方法,在主UI线程里写了创建窗体的方法,然后在新线程里调用。为了更好的实现封装性(新线程所在的类不直接访问主线程所在的类),在主窗口新建一个静态的委托,以便调用:

delegate void delShowForm();
delShowForm _delshowform =null;

在主窗体中把委托和创建窗体的方法名关联起来

public ClientMainForm()
{
InitializeComponent();
_delshowform += ShowForm;//_delshowform=new delegate(ShowForm);这种写法也行
}

在使用到的地方调用
this.Invoke(_delshowform);

在创建窗体的方法中,注意要调用主UI线程的Invoke函数来实现创建窗体,不能使用_delshowform()直接调用。
为了代码精炼,使用了匿名委托和匿名方法

public void ShowForm()
{
//在监听线程里调用这个委托方法
//这里用Invoke表示通过主UI线程创建窗体
//括号里面传入一个匿名的无参Action委托
//委托里传入一个匿名无参方法

this.Invoke(new Action(delegate(){
Form fo = new Form ();
fo.Show();
}));
}

或者换一种写法,利用Invoke来传递参数

public void ShowForm()
{
//通过Invoke传递两个参数
//匿名Action接受两个参数
//Action括号里的匿名方法接受两个参数

this.Invoke(new Action<string>(delegate(string ss){
MessageForm fo = new MessageForm (ss);
fo.Show();
}),
"无");
}

这样写的原因是Invoke函数里面接受的是一个委托,不能直接写入匿名方法,所以用.net内置的Action委托封装了一下匿名方法,再传入函数。
参考别人的记录,然后结合使用,顺便记录下,下次查看方便。