盒子资源分类
一个用 Observer 模式实现的 Thread 线程文件搜索例子
关键字:ThreadFileSearch 观察者模式 多线程 同步 接口 Observer Thread Inteface
来 自:原创
平 台:Win9x,Win2k/XP/NT,Win2003
下载所需:0 火柴
深浅度:中级
完成时间:2006/10/26
发布者:upp
发布时间:2006/10/26
编辑器:BDS2006
语 种:简体中文
分 类:对象
下载浏览:3081/16633
常常在 DFW 或我的群里面看到有朋友询问如何制作多线程程序, 以及如何让线程安全的和界面(或者说窗口)通讯的问题. 由于 VCL 框架并不是线程安全的, 所以导致在线程中如果要更新界面显示, 就必须使用 Synchronize 方法来做同步. 可是一旦这样做, 不可避免的就是在线程中需要声明一个没有参数的过程, 把所有数据暂存到线程的私有变量中, 然后用 Synchronize 来调用此过程, 此过程再直接读取线程私有变量, 直接访问窗体类, 或者其它控件来更新界面的显示. 比较典型的例子就是 Delphi 自己的 Demo, 在 Delphi 安装目录下的 Demo\Threads\thrddemo.dpr 文件. 可是该例子仍然有些不太灵活, 如果显示的控件发生改变, TSortThread 的声明也必须随着改变, 并且这个例子还不能实现一个线程同时对多个视图作出更新的功能 比如线程运行中, 窗体上有多个面板, 需要同时显示多种视图效果; 或者有多个选项卡, 用户随时切换到不同标签下就仅更新该选项卡上控件, 类似这样的功能该例子就无法实现了. 而这些功能又是非常常见的, 比如下载软件中, 更新蚂蚁下载点视图(网际快车中就有), 流量视图, 以及 ListView 中下载字节的统计等. 考虑到这些应用, 比较合适的就是 Observer (观察者) 模式, 不仅可以动态的加入/移出观察者, 也能够让线程类 (Core) 和显示类 (UI) 之间脱耦. 可谓一举多得. 于是我就试着写了个线程搜索路径下所有文件的例子, 在其中应用了 Observer 模式. 此 Demo 已经在 BDS2006 和 Delphi7 下 / WinXp 和 Vista RC2 下编译通过并运行正常. 由于代码说明比较长, 我就把解释都贴在我的博客上了, 欢迎大家去踩踩: 峪飞鹰的Blog: http://blog.sina.com.cn/u/1435615353 一个用 Observer 模式实现的 Thread 线程文件搜索例子(上): http://blog.sina.com.cn/u/5591c079010005pq 一个用 Observer 模式实现的 Thread 线程文件搜索例子(下): http://blog.sina.com.cn/u/5591c079010005pr 例子实际上很简单, 但是可伸缩性和扩展性却比较高. 当然可能也有不足之处. 如果您有任何想法和指教, 可以和我联系: Email: zqw0117@sina.com ********** 注释,由于倏忽,代码中有个Bug,就是在搜索时间超过60秒的时候,会不断的报错.唉,实在汗,写错了一个函数.不好意思. 修改很简单,首先在主窗口单元中的uses语句下,加入DateUtils的引用,然后找到 procedure TTThreadFileSearchDemo.tmrCountTimeTimer(Sender: TObject); 事件处理过程,将其中的代码改为如下即可: var ATime: TTime; begin Inc(FSecondCount); ATime := 0; ATime := IncSecond(ATime, FSecondCount); Caption := Format('Thread Search Demo - 已搜索时间 %s', [TimeToStr(ATime)]); end; 呵呵,代码我就不重上传了, 这个很好改, 大家自己动手吧! :)
本站原创作品,未经作者许可,严禁任何方式转载;转载作品,如果侵犯了您的权益,请联系我们 !
相关文章
相关评论
共有评论16条
当前显示最后6条评论
upp
2006/11/6 14:02:45
是的,因为搜索在repeat里面,所以占用CPU几乎90%以上。我的线程不存在销毁创建的问题,因为生存期就是Searching之间,完成后自行销毁了,下次Search的时候再次创建。所以,victorwoo兄,CPU占用的情况是后者(线程运行的时候导致CPU占用)。 因为本身就是线程,而且可以设置优先级,所以不用太在意这个CPU的占用,一旦有程序需要CPU执行其它高优先级的任务的时候,系统会把更多时间分配给高优先级的程序使用,这个大可不必担心。 不过也有很简单的方法用手工让出CPU时间去处理其它事情,就是在TThreadFileSearch.OnSearch方法中,加一句Sleep(20)即可,这样可将CPU占用降低80%左右(占用平均在20%左右) procedure TThreadFileSearch.OnSearch(Sender: TObject; const BaseDir: string; const FoundRec: TSearchRec); var DoDispatch: TFileFoundSubjectDispatcher; begin if not Terminated then begin DoDispatch := FUpdateSubjectDispatcher; if DoDispatch <> nil then begin DoDispatch.SearchFoundInfo := FoundRec; with DoDispatch.SearchFoundInfo do begin Directory := BaseDir; FullPathName := BaseDir + FoundRec.Name; end; DispatchNotification(fdsSearching); Sleep(20); end; end else FFileSearch.Abort; end;
victorwoo
2006/11/6 14:28:59
嗯,记下这招。 不过我在想一个问题:如果一个线程需要进行大量的IO,例如杀毒软件,那么降低优先级可能会造成IO操作迟缓。其他线程由于IO锁定可能得不到资源。我降低eMule/诺顿的优先级,并没有感觉到系统变快很多。
upp
2006/11/6 19:13:26
要提高IO的访问速度,那只能是换硬件了。呵呵。
victorwoo
2006/11/6 21:42:26
没有啊。比如说你用share deny all方式打开一个文件,这个时候别的进程不能打开此文件了,所以要尽早把这个文件关闭了好。如果这个时候打开文件的线程是超低优先级的,慢慢吞吞才结束,整个系统就感觉拖慢了。
hwwlt
2006/11/7 9:04:41
真心谢谢楼主
winglion
2007/11/7 15:27:13
谢谢阿飞
我要发表评论
查看全部评论