C#读取文件的实时进度条
2016-07-18 11:49
302 查看
C#读取文件的实时进度条
对线程及其线程间通讯,线程访问UI控件的问题没有任何经验,通过编写读取文件的实时进度条来增加一些此方面的基础知识。目的
写过一个用Redis存取数据的小项目,Redis的持久化机制导致在机器crash掉的时候可能会丢失数据,项目也有把检测到的数据写入txt的需求,由于数据txt写入是实时的(每获取一条记录,就写入一条),所以机器crash掉的时候,数据的恢复可以通过读取生成的txt文件来恢复到数据库。由于数据比较多,等待过程漫长,为了增加用户体验以及跟踪实时进度,于是自己想写一个实时进度条。
待解决问题
进度条的总进度的获取如何获取当前读取的进度
进度条实时更新
用多线程解决单线程操作UI页面卡顿问题
思路
进度条的总进度有两种定义:总进度为txt文本文件的行数(数据都是按照行写入),文本文件的大小。如果用文本文件的行数来定义总进度,会导致要通过代码获取文本文件的总行数,计算行数与读取+存储Redis用到了完全相同的代码,这样导致了两次完全相同文件读取,牺牲了一半的效率。通过计算文本文件的大小来定义总长度,每次在读取到一条数据是计算出数据占文本文件大小的百分比,就得到了本次读取的进度。.NET禁止了跨线程调用控件,要通过UI对象的invoke方法,反射调用UI控件的方法。
通过线程间接更改UI控件,UI控件就不会卡顿未响应
ManualResetEvent eventX = new ManualResetEvent(false);//控制线程状态 //获取文件大小 private long len; private long redlen; //获取文件大小(多个文件) private void readFile() { DirectoryInfo di = new DirectoryInfo(restoreFilePath); foreach (FileInfo fi in di.GetFiles()) { len += fi.Length; } string s = (len / 32).ToString(); } //从线程池取线程,用该线程读取文件并存储到redis,直至文件读取完毕,退出线程 public void circleRead() { //files是一个存储txt文件路径的列表 fs = new FileStream(files[index], FileMode.Open); sr = new StreamReader(fs); readFile(); eventX.WaitOne(); while (index < fileCount) { eventX.Reset(); ThreadPool.QueueUserWorkItem(new WaitCallback(changeUIPGBar),new object()); eventX.WaitOne();//直到接收到Set通知,否则阻塞线程 } this.Invoke(new updateLbl(updateState),new object[]{"导入完成"}); } private void button2_Click(object sender, EventArgs e) { //启动一个线程去执行循环读取的线程,异步更新UI界面,这样就不会出现UI线程卡顿 Thread t = new Thread(circleRead); t.IsBackground = true; t.Start(); }
比较重要的方法和数名已经在代码中作出注解
关于后台更新UI线程控件与卡顿问题将会再调查,调查完毕会写博客论述
相关文章推荐
- GUI - Web前端开发框架
- 评价ui设计作品好坏的八个标准(界面/交互设计研究)
- c#调用COM组件
- C#实现把指定数据写入串口
- C#动态创建button的方法
- C#中抽象方法与虚拟方法的区别
- c#中虚函数的相关使用方法
- C#实现给图片加水印的方法
- C#使用加边法计算行列式的值
- C#实现多线程的同步方法实例分析
- C#中尾递归的使用、优化及编译器优化
- C#中的delegate委托类型基本学习教程
- C#实现子窗体与父窗体通信方法实例总结
- C#通用邮件发送类分享
- 举例讲解C#中自动实现的属性
- C#中this的用法集锦
- C#数据结构之顺序表(SeqList)实例详解
- C#.NET获取拨号连接的宽带连接方法
- C#异步绑定数据实现方法
- C#实现AddRange为数组添加多个元素的方法