七天入门C#上位机-界面更新放后台不香嘛
上图中,Winform窗体界面需要实时更新数据和信息显示在主窗体上,那么如何实现这种效果呢?
一、解答
这里其实是运用了线程的知识。现阶段多线程的原理不需要理解很深,但至少还是要了解一些的。
线程主要分为UI线程和CPU线程两种。
UI线程:就是主线程,界面就是在主线程中运行的,与界面有关的数据都会通过UI线程传递到界面上。Winform,Html界面如猎豹浏览器界面等,界面显示都离不开UI线程。
CPU线程:后台线程,主要负责在后台执行任务作业。
二、线程之间的相互作用
多线程的知识本文不过多的解释,后面会出一篇文章详细介绍在上位机中如何运用多线程技术。
现在我们知道,UI线程是负责界面显示交互的,所以,一旦有过多或者很耗时的任务在UI线程上来执行,那么UI线程只能等待它执行完成后才会继续往下走。然而耗时任务往往需要等待很长时间,所以就造成了我们常说的UI线程阻塞,界面就会很卡。
如果想让界面不卡,就不能让过多的任务在UI线程执行,这里是指时间复杂度过高的任务。
对于CPU线程,因为它是独立的,不会阻塞UI线程。所以一般耗时任务都可以放在这里运行。
三、如何使用后台线程
回到本文主题,如何让界面更新放在后台且可以实时更新提高用户体验呢,答案就是启动一个CPU后台线程。然后让CPU线程去执行耗时任务,最后调用UI主线程把结果显示出来。
四、代码如何写?
先写的一个log日志的方法:
public void AddLogMethod(int index, string Log, Exception ex)
{
ListViewItem lst = new ListViewItem(" " + DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"), index);
lst.SubItems.Add(Log);
lstInfo.Items.Insert(0, lst);
if (index == 1)
{
LogHelper.Info(Log);
}
else if (index == 3)
{
LogHelper.Error(Log, ex);
}
}
再调用委托执行;
public void AddLog(int index, string Log, Exception ex)
{
if (this.lstInfo.InvokeRequired)
{
this.lstInfo.Invoke(new Action(() =>
{
AddLogMethod(index, Log, ex);
}));
}
else
{
AddLogMethod(index, Log, ex);
}
}
最后在需要的地方使用就行;
private void FormMain_Load(object sender, EventArgs e)
{
//skinEngine1.SkinFile = Application.StartupPath + @"/Skins/office2007.ssk";
if (Program.currentAdmin.UserRights == "操作员")
{
tSB_Manager.Enabled = false;
}
TimeUp();
timer1.Start();
//this.Resize += new EventHandler(Form1_Resize);//窗体调整大小时引发事件
//X = this.Width;//获取窗体的宽度
//Y = this.Height;//获取窗体的高度
//setTag(this);//调用方法
AddLog(0, "启动软件", null);
}