5

我有一种用 Delphi 编写的拼写检查器。它逐句分析文本。它在解析每个句子后根据一些规则对错误的项目进行着色。用户能够中断这个过程,这很重要。我如何使用一些 3rd 方 Delphi 库来并行化这个过程?在当前状态下,我在检查后立即进行了句子着色。因此,用户可以看到进度。

4

2 回答 2

9

该算法将是这样的:

  • 创建多个工人。
  • 在每个工作人员中创建一个拼写检查器。
  • 抓取文本并将其拆分为工作单元(单词或句子)。每个工作单元都必须附有原文的位置。
  • 将工作单位发送给工人。好的方法是将数据发送到工作人员从中获取工作单元的公共队列中。队列必须支持多个读取器,或者您必须使用锁定来访问它。
  • 每个工人拿一个工作单元,运行拼写检查并将结果(连同原始文本中的位置)返回给所有者。
    • 返回结果的最简单方法是向主线程发送消息。
    • 或者,您可以将结果写入结果队列(必须使用锁定或支持多个写入器),然后应用程序可以轮询这些结果(来自计时器或 OnIdle 处理程序)。

多个拼写检查器如何访问字典是另一个问题。您可以在每个工作人员中加载字典的副本,或者您可以使用锁保护对字典的访问(但这会减慢速度)。如果幸运的话,字典对于阅读来说是线程安全的,并且您可以在不锁定的情况下进行同时查询。

该问题的适当 OmniThreadLibrary 抽象将是ParallelTask​​ 或BackgroundWorker

于 2012-06-15T08:22:05.663 回答
4

要并行化,只需从 TThread 创建一个新的派生类,从中创建一个对象,将部分作业交给新线程,运行 Execute,然后在主线程中收集结果。

像这样:

TMySpellChecker = class(TThread)
protected
  FText: String;
  FResult: String; 
public
  procedure Execute; override;
  property Text: String read FText write FText;
  property Result: String read FResult write FResult;
end;

TMySpellChecker.Execute;
begin
  // Analyze the text, and compute the result
end;

在主线程中:

NewThread := TMySpellChecker.Create(True); // Create suspended
NewThread.Text := TextSegment;
NewThread.Execute;

然后线程对象将在后台进行分析,而主线程继续运行。

要处理结果,您需要为线程对象的 OnTerminate 事件分配一个处理程序:

NewThread.OnTerminate := HandleMySpellCheckerTerminate;

这必须在对线程对象运行 Execute 之前完成。

为了允许中断,一种可能性是将正文分成段,将段放在主线程中的列表中,然后使用线程对象逐个分析段。然后,您可以在每次运行之间允许中断。

于 2012-06-15T08:39:39.710 回答