热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Delphi线程-等待时冻结

如何解决《Delphi线程-等待时冻结》经验,为你挑选了1个好方法。

我正在编写一个需要等到文件存在于目录中的应用程序.我尝试了多种方法,唯一有效的解决方案是使用Sleep/Application.ProcessMessages.

这是我尝试过的:

使用Sleep/Application.ProcessMessages:

Result := False;
for i := 0 to iTimeout do
begin
  if FileExists(fileName) do
  begin
    updateStatus('Conversion Completed');
    Result := True;
    Break;
  end;
  updateStatus(Format('Checking for file: %d Seconds', [i]));
  Application.ProcessMessages;
  Sleep(1000);
end;

此方法有效,但我无法在等待时关闭应用程序.此外,使用Sleep/Application.ProcessMessages还有很好的文档记录问题,我宁愿避免.

使用TThread/TEvent:

type
  TMyThread = class(TThread)
  private
    FEventDone: TEvent;
  public
    constructor Create(CreateSuspended: boolean);
    destructor Destroy;
    procedure Execute; override;
    property EventDone: TEvent read FEventDone;
  end;

  TformThreading = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    waitThread: TMyThread;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  formThreading: TformThreading;

implementation

{$R *.dfm}

{ TformThreading }

procedure TformThreading.Button1Click(Sender: TObject);
var
  res: TWaitResult;
begin
  try
    waitThread.Start;
    res := waitThread.EventDone.WaitFor(INFINITE);
    case res of
      wrSignaled: ShowMessage('wrSignaled');
      wrTimeout: ShowMessage('wrTimeout');
      wrAbandoned: ShowMessage('wrAbandoned');
      wrError: ShowMessage('wrError');
      wrIOCompletion: ShowMessage('wrIOCompletion');
    end;
  except
    on E: Exception do
    begin
      ShowMessage(E.Message);
    end;
  end;
end;

procedure TformThreading.FormCreate(Sender: TObject);
begin
  waitThread := TMyThread.Create(true);
end;

procedure TformThreading.FormDestroy(Sender: TObject);
begin
  waitThread.Free;
end;

{ TMyThread }

constructor TMyThread.Create(CreateSuspended: boolean);
begin
  inherited Create(CreateSuspended);
  FEventDone := TEvent.Create;
end;

destructor TMyThread.Destroy;
begin
  FEventDone.Free;
end;

procedure TMyThread.Execute;
begin
  for i := 0 to iTimeout do
  begin
    if FileExists(fileName) do
    begin
      FEventDone.SetEvent;
      Break;
    end;
    Application.ProcessMessages;
    Sleep(1000);
  end;
end;

我似乎无法让它在等待时不冻结我的主线程,但这似乎是正确的方法,如果我可以解决冻结问题.

解决问题的最佳方法是什么?



1> David Heffer..:

我似乎无法让它在等待时不冻结我的主线程.

等待对象时,该线程会阻塞,直到对象发出信号.因此,当您的主要威胁等待事件时,它将被阻止.您观察到的行为完全符合预期.

查看线程的代码,它会循环,直到满足条件,发出事件信号,然后终止.换句话说,该事件没有任何意义.你可以删除它,而不是等待线程.

现在,如果您这样做,您的代码将执行此操作:

    创建一个线程并开始执行.

    等待该线程完成,阻塞主线程.

    线程完成后继续执行.

所以,就目前而言,你的线程没有任何成就.您也可以在主线程中执行其代码.你回到了起步的地方.

你需要一种不同的心态.GUI程序在其UI中是异步的.你需要遵循这种模式.不要在主线程中等待.相反,一定要使用单独的线程,但在完成后让该线程向主线程发出信号.

这里最简单的方法是OnTerminate为线程实现一个事件处理程序.当线程完成其工作时,它将触发.事件处理程序将在主线程中执行.

更一般地说,您可以使用SynchronizeQueue向主线程发送事件信号,但在您处理终止事件的情况下,您可以满足您的需求.

现在到线程的主体.你的方法是基于轮询和睡眠.这样可行,但并不是非常漂亮.该ReadDirectoryChangesW功能是系统提供的机制,您可以接收文件系统中的更改通知.那将是一种更优雅的方法.

我的建议是首先使用您当前的轮询方法来解决阻塞问题.一旦明确重新使用即可ReadDirectoryChangesW.


推荐阅读
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • vue使用
    关键词: ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 怀疑是每次都在新建文件,具体代码如下 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
author-avatar
草莓公主滴窝窝
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有