捐赠 | 广告 | 注册 | 发布 | 上传 | 关于我们    
  沪ICP备05001939号 DELPHI盒子 | 盒子论坛 | 盒子文章 | 盒子问答悬赏 | 最新更新 | 论坛检索 | 下载中心 | 高级搜索    
  精品专区 | 繁體中文 | 奖励公告栏 | 直通车账号登陆 | 关闭GOOGLE广告 | 临时留言    
盒子资源分类
全部展开 - 全部合拢
一个用 Observer 模式实现的 Thread 线程文件搜索例子
关键字:ThreadFileSearch 观察者模式 多线程 同步 接口 Observer Thread Inteface
来 自:原创
平 台:Win9x,Win2k/XP/NT,Win2003 下载所需:0 火柴
深浅度:中级 完成时间:2006/10/26
发布者:upp 发布时间:2006/10/26
编辑器:BDS2006 语  种:简体中文
分 类:对象 下载浏览:3081/16633
加入到我的收藏
下载错误报错
登陆以后才能下载
 用户名:
 密 码:
自动登陆(30天有效)
图片如果打不开,说明流量不够了,请稍候下载……
常常在 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;
呵呵,代码我就不重上传了, 这个很好改, 大家自己动手吧! :)
Google
 
本站原创作品,未经作者许可,严禁任何方式转载;转载作品,如果侵犯了您的权益,请联系我们
龙脉加密锁 15元起 Grid++Report 报表 申请支付@网
 相关文章
没有相关文章
相关评论
共有评论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
谢谢阿飞
我要发表评论 查看全部评论
 
  DELPHI盒子版权所有 1999-2023 V4.01 粤ICP备10103342号-1 更新RSS列表