2011-12-14 2 views
2

У меня есть Delphi TWebModule Проект на базе ISAPI работает на Apache. Один из моих обработчиков событий содержит логику, которая может занять несколько минут. Я хотел бы создать отдельный процесс/поток для выполнения логики и вернуть html сразу в браузер. Для html-запросов клиентские стороны AJAX будут получать периодические обновления процесса.Нерест новой темы/процесса в обработчике TWebModule

Я попытался с помощью 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. Но это не так. Вместо этого он ждет кода в Выполнение процедуры для завершения.

Как это сделать? Как я создаю асинхронный процесс, чтобы браузер не находился в состоянии ожидания?

+0

Разве вы не можете просто служить страницу, и пусть JavaScript/AJAX клиента инициировать длительный процесс, а? –

+1

Угадайте, я мог бы попробовать это. AJAX для меня немного нова. И в идеале я бы не хотел, чтобы клиентский процесс инициировал этот процесс. Скорее полагаться на серверную сторону. –

+0

Прежде чем отвечать на вопросы, важно задать несколько вопросов: 1. Является ли мое предположение, что это веб-приложение, обслуживаемое веб-сервером? 2. ISAPI или CGI? –

ответ

2

Просто вращающийся ответ Дариана. Вот пример, который отвечает на ваш вопрос:

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; 
+0

Хорошо - куда-то сюда. Я изменил свой класс потомков, включив «FreeOnTerminiate = True», и когда я его создал, он изменил CreateSuspended с True на False. Перед тем, как я вызвал конструктор с CreateSuspended = True и затем вызвал Execute. –

+0

Хорошо, просто не вызывайте явно '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 
+0

Не удалось найти класс TProcessThread. Искал весь код CodeGear Delphi 2007. –

+0

@Darian, в Delphi 2007 еще нет ['TThread.Start'] (http://docwiki.embarcadero.com/VCL/en/Classes.TThread.Start) (я знаю, что версия Delphi отсутствует в этом вопросе). Исправлено: – TLama

+1

Нет необходимости создавать приостановленную цепочку. Просто установите 'FreeOnTerminate: = True 'в методе создания потока. –

Смежные вопросы