【发布时间】:2014-09-22 20:20:57
【问题描述】:
在使用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'有什么问题呢?
【问题讨论】:
-
不只是在 OnTaskMessage 事件处理程序中设置标题,而是将消息放入备忘录或类似文件中以进行调试。调试时,在 TestParameters 中放置一个断点并单步执行所有行。在没有调用 FTestTask.Terminate 和 FTestTask := nil 的情况下测试 Assigned(FTestTask) 似乎很奇怪。
-
@LURD 我已经按照你说的做了,并逐步完成了TestParameters:在参数访问行中,我遇到了一个异常
TOmniValueContainer.Getltem: Parameter From does not exist。所以很明显SetParameters有问题,顺便说一句,它完全遵循 OmniThread 文档中的解释。 -
它似乎只能以这种方式工作:
test := ATask.Param.ByName('From');AND 而不是SetParameters与使用.SetParameter('From', 1).SetParameter('To', 99)等的多次调用的开放数组。 -
这是当前 SetParameter 实现中的一个错误。当我向 TOmniValue 添加数组支持时,底层存储发生了变化,并且未修改 SetParameters 以反映该变化。我会尽快解决这个问题。
-
@gabr 谢谢。你能告诉我如何在 SetParameter 中传递(然后访问)一个 TRect 吗?不支持
.SetParameter('FormRect', Self.ClientRect)。
标签: delphi parallel-processing delphi-xe2 omnithreadlibrary