由于项目中存在这样的载入的画面:在界面上有显示载入信息的Label控件和进度条,如果采用单线程则在载入数据的时候UI界面会被锁死,造成假死的感觉。为了给一个更友好的界面,因此有必要引入多线程技术,使得软件更加“人性化”。
但随后在子线程中访问界面上的控件的时候会出现异常,不能操作主线程所控制的UI界面。看来这得用到委托技术了!
首先我们定义委托:
public delegate void loadin(string data, int progress);
定义委托用delegate关键字,随后跟着一个返回值(这里void就是没有返回值了),loadin是委托名,后面带着两个参数,分别代表显示载入的数据和载入进度条的数值!
在窗体的Load事件里面我们定义一个子线程,用于在后台载入数据并显示载入情况。
定义线程:
ThreadStart ts = new ThreadStart(Downin); //括号里面的参数是一个方法名,表示线程要处理的方法
Thread mythread = new Thread(ts);
mythread.Start(); //线程开始运作
以上三行是线程操作的核心内容,不熟悉线程定义和执行原理等的园友请参考《C#线程参考手册》!
然后我们在Downin方法里面实例化委托并调用之。(这里“实例化”似乎用得不妥,但其实委托和类有很多地方是相似的)
private void Downin()
{
loadin di = new loadin(Update); //委托后面的参数跟着一个方法名
this.Invoke(di, "正在初始化系统", 5); //调用委托所关联的方法,并传递两个参数
Thread.Sleep(500); //线程停止工作0.5秒
this.Invoke(di, "正在载入配置信息",35);
Thread.Sleep(500);
this.Invoke(di, "正在载入用户数据",70);
Thread.Sleep(500);
this.Invoke(di, "正在完成",100);
Thread.Sleep(500);
Thread.CurrentThread.Abort(); //当前线程(子线程)终止
}
委托其实就是充当方法的签名,这里委托的参数就是一个方法名,这个方法名带有两个参数,和委托参数表是一样的,同时返回类型也是一样!
private void Update(string data,int progress) //在info标签上显示载入信息
{
this.info.Text = data.ToString();
this.progressBar.Value = progress;
}
就这样我们绕了一圈,“间接”得通过委托访问主线程构建的控件。
本文只是抛砖引玉,可以了解一下线程和委托的好处。当然,线程并不是越多越好,否则只会增加系统开销,应该看实际需要来应用。
注:如有疏漏之处请指教,谢谢。