【C#Winform】一个多线程扫描本地磁盘目录文件个数的Demo
2013-04-11 11:05
483 查看
扫描本地磁盘目录是个巨大的工程,扫描文件个数更是个巨大的工程。
单线程在处理大型任务的时候是很难胜任的 或者说很难有什么可接受的效率
多线程比单线程的最大优势是可以把巨大的任务分割成小任务并发进行
然后把每个线程的执行结果汇总
其实巨大的任务分得越细 多线程就比单线程约有优势
下面将来完成上图界面的扫描计数功能
其中左右两边的加载树形结构的控件是TreeView
下面显示消息的是ListView 其他的控件很明显 就不说明了。
好吧 直接看代码:
此代码测试很稳定 暂时没有发现什么bug
如果有问题 可以回复我
单线程在处理大型任务的时候是很难胜任的 或者说很难有什么可接受的效率
多线程比单线程的最大优势是可以把巨大的任务分割成小任务并发进行
然后把每个线程的执行结果汇总
其实巨大的任务分得越细 多线程就比单线程约有优势
下面将来完成上图界面的扫描计数功能
其中左右两边的加载树形结构的控件是TreeView
下面显示消息的是ListView 其他的控件很明显 就不说明了。
好吧 直接看代码:
public partial class fCodeManage : Form { List<System.Threading.Thread> ts; //System.Text.StringBuilder msg = new StringBuilder(); Color treeNodeColor; public fCodeManage() { InitializeComponent(); } private void TestTool_Load(object sender, EventArgs e) { Init(); } protected void Init() { this.tvDir.Nodes.Clear(); this.tvSelDir.Nodes.Clear(); this.tvDir.Nodes.Add(new TreeNode("我的电脑/My PC")); this.tvSelDir.Nodes.Add(new TreeNode("选择目录/Selected Directory")); DriveInfo[] drives = System.IO.DriveInfo.GetDrives(); this.tvDir.TopNode.ToolTipText = string.Format("拥有{0}个磁盘", drives.Length); foreach (DriveInfo di in drives) { if (di.IsReady) { this.tvDir.TopNode.Nodes.Add(new TreeNode(di.Name, new TreeNode[] { new TreeNode() })); } } this.tvDir.TopNode.Expand(); } private void bAdd_Click(object sender, EventArgs e) { TreeNode selNode = this.tvDir.SelectedNode; if (selNode == null) { MessageBox.Show("请选择一个节点"); return; } if (treeNodeColor == Color.Empty) { treeNodeColor = selNode.ForeColor; } List<TreeNode> findResult = new List<TreeNode>(); foreach (TreeNode tn in this.tvSelDir.TopNode.Nodes) { if (tn.Text.IndexOf(selNode.Text) != -1) { if (tn.Tag != null && ((TreeNode)tn.Tag == selNode || SearchNode(selNode.Nodes, (TreeNode)tn.Tag))) { findResult.Add(tn); } } } foreach (TreeNode tn in findResult) { this.tvSelDir.TopNode.Nodes.Remove(tn); ((TreeNode)tn.Tag).Nodes.Add(tn); } if (selNode != this.tvDir.TopNode) { selNode.Tag = selNode.Parent; } this.tvDir.Nodes.Remove(selNode); this.tvSelDir.TopNode.Nodes.Add(selNode); this.tvSelDir.TopNode.Expand(); } private void bDel_Click(object sender, EventArgs e) { TreeNode selNode = this.tvSelDir.SelectedNode; if (selNode == null) { MessageBox.Show("请选择一个节点"); return; } if (selNode == this.tvSelDir.TopNode||selNode.Parent!=this.tvSelDir.TopNode) { MessageBox.Show("您不能删除该节点"); return; } selNode.Parent.Nodes.Remove(selNode); if (selNode.Tag != null) { ((TreeNode)selNode.Tag).Nodes.Add(selNode); } else { this.tvDir.Nodes.Add(selNode); } } protected bool SearchNode(TreeNodeCollection nodeList, TreeNode findNode) { foreach (TreeNode tn in nodeList) { if (tn == findNode || tn.Text == findNode.Text) { return true; } if(findNode.Text.IndexOf(tn.Text)!=-1){ if (tn.Nodes.Count > 0) { return SearchNode(tn.Nodes, findNode); } } } return false; } private void tvDir_BeforeExpand(object sender, TreeViewCancelEventArgs e) { if (string.IsNullOrEmpty(e.Node.ToolTipText)) { try { string[] dirs = System.IO.Directory.GetDirectories(e.Node.Text); e.Node.ToolTipText = string.Format("拥有{0}个子目录", dirs.Length); e.Node.Nodes.Clear(); foreach (string dir in dirs) { e.Node.Nodes.Add(new TreeNode(dir, new TreeNode[] { new TreeNode() })); } } catch(Exception ex) { e.Node.ToolTipText = string.Empty; e.Node.Nodes.Clear(); e.Node.Nodes.Add(new TreeNode()); this.lbMsg.Items.Add(string.Format("获取{1}子目录发生错误,请稍候再试,错误内容为:{0}", ex.Message,e.Node.Text)); } } } private void tvSelDir_BeforeExpand(object sender, TreeViewCancelEventArgs e) { if (e.Node == ((TreeView)sender).TopNode) { return; } tvDir_BeforeExpand(sender, e); } private void bReload_Click(object sender, EventArgs e) { Init(); } private void tvSelDir_BeforeSelect(object sender, TreeViewCancelEventArgs e) { if (e.Node.Parent != ((TreeView)sender).TopNode) { e.Cancel = true; } } private void bClose_Click(object sender, EventArgs e) { this.Close(); } private void TestTool_FormClosing(object sender, FormClosingEventArgs e) { this.Dispose(true); Application.Exit(); System.Environment.Exit(0); } private void tvDir_BeforeSelect(object sender, TreeViewCancelEventArgs e) { if (e.Node == ((TreeView)sender).TopNode) { e.Cancel = true; } } private void bRun_Click(object sender, EventArgs e) { if (this.tvSelDir.TopNode.Nodes.Count <= 0) { MessageBox.Show("没有要检查的目录"); return; } int threadCount = Convert.ToInt32(this.nupThreadCount.Value); this.ts = new List<System.Threading.Thread>(); for (int i = 0; i < threadCount; i++) { ts.Add(new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(DoWork))); ts[i].Name = string.Format("iRightCodeManage_{0}", i+1); ts[i].Start(ts[i]); } if (this.lbMsg.Items.Count > 0) { this.lbMsg.Items.Add("---------------------------"); } this.lbMsg.Items.Add(string.Format("{0}个线程{1}开始运行,请耐心等待处理结果!", threadCount,System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))); } protected void DoWork(object thread) { System.Threading.Thread currentThreading = thread as System.Threading.Thread; string tIndex = currentThreading.Name.Split('_')[1]; TreeNode tn2Work = null; do { tn2Work = null; lock (this.tvSelDir.TopNode.Nodes) { foreach (TreeNode tn in this.tvSelDir.TopNode.Nodes) { if (tn.ForeColor != Color.Red && tn.ForeColor != Color.Green) { tn.ForeColor = Color.Red; tn2Work = tn; break; } } } if (tn2Work != null) { int fileCount = 0; DoWordOfDir(tn2Work.Text, ref fileCount); //msg.AppendFormat("目录【{0}】有{1}个文件", tn.Text, fileCount); this.lbMsg.Items.Add(string.Format("第{2}个线程处理完毕,目录【{0}】有{1}个文件", tn2Work.Text, fileCount, tIndex)); tn2Work.ForeColor = Color.Green; } } while (tn2Work != null); this.lbMsg.Items.Add(string.Format("第{0}个线程已终止", tIndex)); ts.Remove(currentThreading); currentThreading.Interrupt(); if (ts == null || ts.Count <= 0) { foreach (TreeNode tn in this.tvSelDir.TopNode.Nodes) { tn.ForeColor = treeNodeColor; } this.lbMsg.Items.Add(string.Format("全部线程在{0}完成任务。", System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))); this.lbMsg.Items.Add("---------------------------"); } currentThreading.Abort(); } protected void DoWordOfDir(string dirPath,ref int fileCount) { try { System.IO.DirectoryInfo fi = new System.IO.DirectoryInfo(dirPath); fi.SetAccessControl(new System.Security.AccessControl.DirectorySecurity(dirPath, System.Security.AccessControl.AccessControlSections.Access)); FileSystemInfo[] fsis = fi.GetFileSystemInfos(); foreach (FileSystemInfo fsi in fsis) { if (fsi is System.IO.DirectoryInfo) { DoWordOfDir(fsi.FullName, ref fileCount); } else if (fsi is System.IO.FileInfo) { fileCount++; } } } catch { } } private void bThreadClear_Click(object sender, EventArgs e) { if (this.ts == null || this.ts.Count <= 0) { MessageBox.Show("没有要清除的线程!"); return; } foreach (System.Threading.Thread t in ts) { if (t != null) { t.Abort(); } } ts = null; MessageBox.Show("线程清除完毕!"); } private void bMsgClear_Click(object sender, EventArgs e) { this.lbMsg.Items.Clear(); } }
此代码测试很稳定 暂时没有发现什么bug
如果有问题 可以回复我
相关文章推荐
- c# winform项目treeview控件绑定本地电脑磁盘信息,读取文件夹信息,显示文件夹内文件内容
- c# winform项目treeview控件绑定本地电脑磁盘信息,读取文件夹信息,显示文件夹内文件内容
- 在Asp.net中如何遍历一个本地目录下的所有文件并上载到Web 服务器上指定的目录中
- c# 多线程的一个小Demo
- C# 自动查找文件内容(正则使用、获取目录下所有文件、多线程、日志记录,文件操作)
- c#读取xml文件配置文件Winform及WebForm-Demo详解
- Demo11 :目录操作(列目录下的文件和移动一个目录)
- 怎样用Java.net.URL表示一个本地目录下的文件?
- C# winform中选择本地文件,并获取其路径
- c#winform选择文件,文件夹,打开指定目录方法
- C#监控本地目录文件变化
- C# 多线程目录拷贝 文件拷贝
- C#/.net学习-13-一个多线程的摇奖winform小程序
- C#制作文本转换为声音的demo,保存音频文件到本地
- C# WinForm 通过URL取得服务器上的某图片文件到本地
- C# 系统应用之TreeView控件 (一).显示树状磁盘文件目录及加载图标
- c#winform选择文件,文件夹,打开指定目录方法
- 在WinForm/C#中打开一个文件
- C#使用WebClient下载文件到本地目录
- 扫描一个目录下的所有文件,根据这些文件的创建日期生成一个文件夹,然后把这些文件移入这个文件夹下面