Delphi 访问全线程并行任务中的参数将中止该任务
在使用OmniThread库创建并行任务的程序中,当我尝试访问并行任务中的参数时,参数访问后的代码不会执行,因此任务显然会中止:Delphi 访问全线程并行任务中的参数将中止该任务,delphi,parallel-processing,delphi-xe2,omnithreadlibrary,Delphi,Parallel Processing,Delphi Xe2,Omnithreadlibrary,在使用OmniThread库创建并行任务的程序中,当我尝试访问并行任务中的参数时,参数访问后的代码不会执行,因此任务显然会中止: uses System.SysUtils, System.Classes, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, OtlComm, OtlTask, OtlTaskControl, OtlEventMonitor; type TForm1 = class(TForm) btn
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;
使用
System.SysUtils、System.class、,
Vcl.控件、Vcl.窗体、Vcl.对话框、Vcl.stdctrl、,
OtlComm、OtlTask、OtlTask控制、OtlEventMonitor;
类型
TForm1=类(TForm)
btnStartOTLTask:TButton;
OTLMonitor:TOmniEventMonitor;
程序btnStartOTLTaskClick(发送方:TObject);
过程OTLMonitorTaskMessage(常量任务:IOmniTaskControl;常量消息:
TOmniMessage);
私有的
{私营部门}
FTestTask:IOmniTaskControl;
公众的
{公共部门}
结束;
变量
表1:TForm1;
实施
{$R*.dfm}
{在窗体上放置TOmniEventMonitor组件,
命名为OTLMonitor
并实现OnTaskMessage事件处理程序:OTLMonitorTaskMessage}
程序测试参数(常数ATask:IOmniTask);
变量
测试:整数;
开始
ATask.Comm.Send(16);//执行
测试:=ATask.Param['From'];/ 我找到了一个解决办法:
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;
不只是在OnTaskMessage事件处理程序中设置标题,而是将消息放入备忘录或类似文件中进行调试。调试时,在TestParameters中放置一个断点,并逐步遍历所有行。在没有调用FTestTask的情况下测试已分配的(FTestTask)。Terminate和FTestTask:=nil似乎很奇怪。@LURD我已经按照您所说的做了,并逐步完成了测试参数:在具有参数访问权限的行中,我得到了一个异常TOmniValueContainer.Getltem:来自的参数不存在
。所以显然,SetParameters
有问题,顺便说一句,它完全遵循了OmniThread文档中的解释。它似乎只以这种方式工作:test:=ATask.Param.ByName('From')
而不是SetParameters
,使用多个调用.SetParameter('From',1)。SetParameter('To',99)
等打开数组。这是当前SetParameter实现中的一个错误。当我向TOmniValue添加阵列支持时,底层存储发生了变化,并且没有修改SetParameters以反映这种变化。我会尽快修好的。@gabr谢谢。您能告诉我如何在SetParameter中传递(然后访问)树吗.SetParameter('FormRect',Self.ClientRect)
不受支持。