【问题标题】:Spawning a new thread/process within TWebModule Handler在 TWebModule 处理程序中生成一个新线程/进程
【发布时间】:2012-01-20 07:06:12
【问题描述】:

我有一个在 Apache 上运行的基于 Delphi TWebModule ISAPI 的项目。我的一个事件处理程序包含可能需要几分钟才能处理的逻辑。我想生成一个单独的进程/线程来执行逻辑并将 html 立即返回给浏览器。该 html 将具有 AJAX 客户端调用以获取进程进度的定期更新。

我曾尝试使用 TThread,但发现它会等待 Execute 代码结束后再返回。

例子:

  procedure Tmainweb.DoLongProcess(Sender: TObject; Request: TWebRequest;
    Response: TWebResponse; var Handled: Boolean);
  var
    ProcessThread: TProcessThread;
  begin
    ProcessThread := TProcessThread.Create(True);
    ProcessThread.Execute;
    Handled := True;
    Response.Content := '<html><body>Processing - would also include ajax stuff to get periodic updates</body></html>
  end;

TProcessThread 是我的处理线程,可能需要几分钟才能完成。当我运行这个应用程序时,我认为控制会在 ProcessThread.Execute 之后立即继续。但事实并非如此。相反,它会等待 Execute 过程中的代码完成。

我怎样才能做到这一点?如何生成异步进程以使浏览器不处于等待状态?

【问题讨论】:

  • 你不能只提供页面并让 javascript/ajax 客户端启动漫长的过程吗?
  • 我想我可以试试。 AJAX 对我来说有点新。理想情况下,我不希望客户端启动此过程。宁愿依赖服务器端来。
  • 在回答之前,问一些问题很重要: 1. 我是否假设这是一个由 Web 服务器提供的 Web 应用程序? 2. ISAPI 还是 CGI?
  • 好吧,最终还是由客户端(浏览器)发起进程(通过访问 URL)。
  • @NickHodges:Apache 上的 ISAPI。

标签: delphi delphi-2007


【解决方案1】:

只是在 Darian 的回答上旋转。 这是一个回答您问题的示例:

type
  TProcessThread = class(TThread)
  protected 
    procedure Execute; override;
  public
    constructor Create;
  end;

constructor TProcessThread.Create;
begin
 inherited Create( false);
 Self.FreeOnTerminate := true;
end;

procedure TProcessThread.Execute;
begin
  while not Self.Terminated do begin
    {- Do some heavy work }
  end;
  {- free by myself at last ! }
end;

-

// In your TmainWeb.DoLongProcess
ProcessThread := TProcessThread.Create; // Thread will free itself when ready.
Handled := True;

【讨论】:

  • 好的 - 到达这里。我修改了我的后代类以包含“FreeOnTerminate = True”,并且当我创建它时,将 CreateSuspended 从 True 更改为 False。在我使用 CreateSuspended = True 调用构造函数然后调用 Execute 之前。
  • 好,只是不要显式调用Execute,因为这是由线程类本身完成的。
【解决方案2】:

没有足够的信息来给出正确的答案,但我假设 TProcessThread 以某种方式从 TThread 继承。如果是这样,那么您创建线程,然后启动它。 execute方法会在子线程中调用,不能直接调用。

ProcessThread.FreeOnTerminate := True
ProcessThread.Start() // Later versions of Delphi
//or  ProcessThread.Resume;  in earlier versions of Delphi to start a suspended thread

【讨论】:

  • 我找不到 TProcessThread 类。搜索了所有 CodeGear Delphi 2007 代码。
  • @Darian,在 Delphi 2007 中还没有 TThread.Start(我知道这个问题中缺少 Delphi 版本)。固定:)
  • 不需要创建线程挂起。只需在线程创建方法中设置FreeOnTerminate := True;
  • @MSchenkel,TProcessThread 类是您可以在代码中定义的东西,它是从TThread 派生的类。否则你的问题不清楚。
  • 如果 .Start() 不可用,请使用 .Resume()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
相关资源
最近更新 更多