2012-11-23 75 views
3

我想在响应生产者后做一些工作。德尔福WebBroker/ISAPI与线程

为了不保留时间响应,我试图在一个线程中完成这项工作。

这个线程创建一个DataModule,并执行某些东西(发送电子邮件,处理文件操作等),但执行阻塞了主线程。

我不使用变量或与主线程的任何其他交互。我没有看到任何可以发行块的东西。

任何人都可以帮忙吗?

线程代码:


unit wdm_Thread; 

interface 

uses 
    System.SysUtils, System.Classes, Web.HTTPApp, Web.HTTPProd, Web.DSProd,Data.DB, Data.Win.ADODB; 

type 
    TwdmThread = class(TDataModule) 
     dbConnection: TADOConnection; 
     spVisualizador: TADOStoredProc; 
     spVisualizadorProc: TADOStoredProc; 
     spVisualizadorProcFim: TADOStoredProc; 
     spVisualizadorProcInicio: TADOStoredProc; 
     ppVisualizadorOn: TDataSetPageProducer; 
     spVisualizadorMiniProc: TADOStoredProc; 
    end; 

    colaboreThread = class(TThread) 
    private 
     FDataModule: TwdmThread; 
     FPreviewPath: String; 
     FSessionID: String; 
     FUniqueID: String; 
     FUniqueIDVersao: String; 
    public 
     procedure Execute(); override; 
     class procedure Thumbnail(APreviewPath, ASessionID, AUniqueID, AUniqueIDVersao: String); 
    end; 

implementation 

uses 
    WinAPI.Windows, WinAPI.ActiveX; 

{%CLASSGROUP 'System.Classes.TPersistent'} 

{$R *.dfm} 

{ threadThumbnail } 

procedure colaboreThread.Execute; 
begin 
    try 
     FDataModule := TwdmThread.Create(nil); 
     with FDataModule do 
     begin 
      spVisualizador.Parameters[1].Value := FSessionID; 
      spVisualizador.Parameters[2].Value := FUniqueID; 
      spVisualizador.Parameters[3].Value := FUniqueIDVersao; 
      spVisualizador.Parameters[4].Value := False; 
      spVisualizador.Open(); 

      if spVisualizador.RecordCount > 0 then 
      try 
       DeleteFile(PWideChar(FPreviewPath + FUniqueIDVersao + spVisualizador.FieldByName('Extensao').AsString)); 

       CopyFile(PWideChar(spVisualizador.FieldByName('ArmazenamentoCaminho').AsString + FUniqueIDVersao), PWideChar(FPreviewPath + FUniqueIDVersao + spVisualizador.FieldByName('Extensao').AsString), true); 

       spVisualizadorMiniProc.Parameters[1].Value := FSessionID; 
       spVisualizadorMiniProc.Parameters[2].Value := FUniqueID; 
       spVisualizadorMiniProc.Parameters[3].Value := FUniqueIDVersao; 
       spVisualizadorMiniProc.Parameters[4].Value := FPreviewPath; 
       spVisualizadorMiniProc.ExecProc(); 
      finally 
       DeleteFile(PWideChar(FPreviewPath + FUniqueIDVersao + spVisualizador.FieldByName('Extensao').AsString)); 
     end 
    end; 
    finally 
    FreeAndNil(FDataModule); 
    end; 

end; 

class procedure colaboreThread.Thumbnail(APreviewPath, ASessionID, AUniqueID, AUniqueIDVersao: String); 
begin 
    with colaboreThread.Create(True) do 
    begin 
    FreeOnTerminate := True; 
    FPreviewPath := APreviewPath; 
    FSessionID := ASessionID; 
    FUniqueID := AUniqueID; 
    FUniqueIDVersao := FUniqueIDVersao; 
    if FUniqueIDVersao = '' then FUniqueIDVersao := FUniqueID; 

    Execute(); 
    end; 
end; 

initialization 
    CoInitializeEx(NIL, COINIT_MULTITHREADED or COINIT_SPEED_OVER_MEMORY); 

end. 

WebModule实现:


... 

procedure TwdmColaboreUP.wdmTopWebUploadwaiUploadAction(Sender: TObject; 
    Request: TWebRequest; Response: TWebResponse; var Handled: Boolean); 
begin 
    colaboreThread.Thumbnail(FPreviewPath, FSessionID, FArquivoUniqueID, FArquivoUniqueIDVersao); 
end; 

... 
+2

如果没有正确的解释或代码,我们如何猜测? – jachguate

+0

感谢您的关注。我不把代码放在第一位,但现在我做到了。 – adam9k

回答

3

您所呼叫的线程上Execute,但你不应该直接调用它。您使用Resume(或通过在其构造函数中省略暂停参数)启动线程。然后,Execute方法将在后台启动。

如果您开始自己执行,就像您现在执行的那样,它会像任何其他方法一样在主线程中运行。

with colaboreThread.Create(True) do 
    begin 
    FreeOnTerminate := True; 
    FPreviewPath := APreviewPath; 
    FSessionID := ASessionID; 
    FUniqueID := AUniqueID; 
    FUniqueIDVersao := FUniqueIDVersao; 
    if FUniqueIDVersao = '' then FUniqueIDVersao := FUniqueID; 

    // Execute(); <--- Not this 

    Resume; // <--- but this 
    end; 
+0

现在完美...非常感谢你! – adam9k