Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 访问全线程并行任务中的参数将中止该任务_Delphi_Parallel Processing_Delphi Xe2_Omnithreadlibrary - Fatal编程技术网

Delphi 访问全线程并行任务中的参数将中止该任务

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

在使用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;
使用
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)
不受支持。