首页 > 代码库 > Winform之跨线程访问控件(在进度条上显示字体)
Winform之跨线程访问控件(在进度条上显示字体)
此文章对于遇到必须使用线程但是没有办法在线程内操作控件的问题的处理 有很好的解决方案(个人认为的。有更好的方案欢迎交流。)
在做跨线程访问之前我们先了解下我们所做的需要达到的效果:
这个是批量的将xml文件导入sqlite数据库 每个xml有将近3000的节点 每个节点有5个属性,如果我们不用线程那么在数据导入的过程中 程序很可能卡死 而且基本上动不了,用户的体验性就很差。
所以我们对向数据库添加数据的地方使用了线程:
Thread thread = new Thread(new ThreadStart(() => { try { ExeInsertDatabase(); //数据导入 } catch (Exception ex) { MessageBox.Show(ex.Message, "导入提示"); return; } })); thread.Start();
线程是很好创建 但是毕竟xml文件太多 即使每一个只需要1-2秒 但是几千个xml要几分钟的时间,在这个过程中我们需要让用户看到这个进度。那么 加一个进度条:
Font font = new Font("微软雅黑", (float)8, FontStyle.Regular); //进度条上显示的字体 PointF pointF = new PointF(this.pbImport.Width / 4 - 10, this.pbImport.Height / 2 - 8); //字体显示的位置 pbImport.Value = http://www.mamicode.com/0; pbImport.Minimum = 0; pbImport.Step = 1;this.pbImport.CreateGraphics().DrawString("正在导入(这里写导入的文件名称或者是导入的进度等信息)", font, Brushes.Black, pointF);
看到这里你就想到了 数据库插入数据 在线程里面 进度条的增长是不是也要在线程里面加入? 是不是要写上this.pbImport.Value++;? this.pbImport.CreateGraphics().DrawString("正在导入(这里写导入的文件名称或者是导入的进度等信息)", font, Brushes.Black, pointF); 这个是不是也要加入到线程内才能刷新进度条的进度信息?
你可以试试。。。
那么会出现如下错误:
从不是创建控件 “控件名称”的线程访问它
yes 下面就是这个问题的解决方案:
private delegate void SetImportM(); private void ImportMessage() { if (this.InvokeRequired) { SetImportM s = new SetImportM(ImportMessage); this.Invoke(s); } else { string strText = "正在导入文件" + filePaths[index] + "..." + (index + 1) + "/" + filePaths.Count; this.pbImport.CreateGraphics().DrawString(strText, font, Brushes.Black, pointF); } }
我们使用了委托解决这个问题用来追加数据库的进度, 只需要在向数据库插入数据的地方去调用这个方法就ok了!
啰嗦了这么多其实这个很简单。
假如还有不明白的童鞋 请看右下角 本人提供特殊服务。。。。。
.Net、WPF 技术交流群 : 9234450
不管你遇到了什么问题,我们绝不会让你独自去面对!
Winform之跨线程访问控件(在进度条上显示字体)