2014-09-22 74 views
1

在使用OmniThread庫創建並行任務的程序中,當我嘗試訪問並行任務中的參數時,參數訪問後面的代碼未執行,因此顯然任務被中止:在OmniThread並行任務中訪問參數將中止任務

uses 
    System.SysUtils, System.Classes, 
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, 

    OtlComm, OtlTask, OtlTaskControl, OtlEventMonitor; 

type 
    TForm1 = class(TForm) 
    btnStartOTLTask: TButton; 
    OTLMonitor: TOmniEventMonitor; 
    procedure btnStartOTLTaskClick(Sender: TObject); 
    procedure OTLMonitorTaskMessage(const task: IOmniTaskControl; const msg: 
     TOmniMessage); 
    private 
    { Private-Deklarationen } 
    FTestTask: IOmniTaskControl; 
    public 
    { Public-Deklarationen } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

{ Place a TOmniEventMonitor component on the form, 
    name it OTLMonitor 
    and implement the OnTaskMessage event-handler: OTLMonitorTaskMessage } 

procedure TestParameters(const ATask: IOmniTask); 
var 
    test: Integer; 
begin 
    ATask.Comm.Send(16); // does execute 
    test := ATask.Param['From']; // ?? <<<=========================== 
    ATask.Comm.Send(17); // does NOT execute! 
end; 

procedure TForm1.btnStartOTLTaskClick(Sender: TObject); 
begin 
    if not Assigned(FTestTask) then // prevent multiple tasks 
    FTestTask := CreateTask(TestParameters, 'TestParameters') 
        .MonitorWith(OTLMonitor) 
        .SetParameters(['From', 0, 'To', 99]) 
        .Run 
    else 
    MessageDlg('Task is already running!', mtInformation, [mbOK], 0); 
end; 

procedure TForm1.OTLMonitorTaskMessage(const task: IOmniTaskControl; const msg: TOmniMessage); 
begin 
    Self.Caption := IntToStr(msg.MsgID); 
end; 

那麼訪問參數'From'有什麼問題?

+1

而不是隻需設置標題在OnTaskMessage事件處理程序,消息放入備忘錄或類似的調試。調試時,在TestParameters中放置一個斷點並遍歷所有行。在沒有調用FTestTask.Terminate和FTestTask的情況下測試分配的(FTestTask):= nil看起來很奇怪。 – 2014-09-22 21:02:00

+0

@LURD我已經按照你所說的完成了,並且通過了TestParameters:在參數訪問行中,我得到了一個'TOmniValueContainer.Getltem:Parameter From does not exist'異常。所以很顯然,'SetParameters'有問題,順便說一句,它遵循OmniThread文檔中的解釋。 – user1580348 2014-09-22 21:45:28

+0

它似乎只能以這種方式工作:'test:= ATask.Param.ByName('From');'而不是'SetParameters'開放數組使用'.SetParameter('From',1 ).SetParameter('To',99)'等 – user1580348 2014-09-22 21:58:14

回答

2

我已經找到了解決辦法:

procedure TestParameters(const ATask: IOmniTask); 
begin 
    // this does work: 
    ATask.Comm.Send(ATask.Param.ByName('From')); 
    ATask.Comm.Send(ATask.Param.ByName('To')); 

    // ALSO this does work: 
    ATask.Comm.Send(ATask.Param['From']); 
    ATask.Comm.Send(ATask.Param['To']); 
end; 

procedure TForm1.btnStartOTLTaskClick(Sender: TObject); 
begin 
    if not Assigned(FTestTask) then // prevent multiple tasks 
    FTestTask := CreateTask(TestParameters, 'TestParameters') 
        .MonitorWith(OTLMonitor) 
        // SetParameters does not work: 
        //.SetParameters(['From', 1, 'To', 99]) 
        // this does work: 
        .SetParameter('From', 1) 
        .SetParameter('To', 99) 
        .Run 
    else 
    MessageDlg('Task is already running!', mtInformation, [mbOK], 0); 
end; 

procedure TForm1.OTLMonitorTaskMessage(const task: IOmniTaskControl; const msg: TOmniMessage); 
begin 
    Memo1.Lines.Add(IntToStr(msg.MsgID)); 
end; 

procedure TForm1.OTLMonitorTaskTerminated(const task: IOmniTaskControl); 
begin 
    FTestTask := nil; 
    Memo1.Lines.Add('Task terminated'); 
end;