【问题标题】:Pass TStringList to TOmniTask procedure将 TStringList 传递给 TOmniTask 过程
【发布时间】:2014-09-19 13:05:35
【问题描述】:

我在 Delphi 2007 应用程序中使用 OmniThreadLibrary,该应用程序利用全局线程池执行一些文件操作(我需要尝试并确保它们按特定顺序完成)。

我有一个新创建的 Ini 文件的内容,该文件存储在 TStringList 中。

然后我将 TStringList 传递给 TOmniTask 的一个实例。

class procedure saveIniFile(const iniFile: TStringList);
    var
        task  : IOmniTaskControl;
    begin
        task := CreateTask(saveIniFileTask, 'saveIniFile')
                   .SetParameter('iniFile', iniFile)
                   .Unobserved
                   .Schedule;
    end;

我不知道如何在 TOmniTask 实例中检索 TStringList

class procedure saveIniFileTask(const task: IOmniTask);
    var
        iniFile: TStringList;
    begin
        iniFile := task.Param['iniFile'];
    end;

上面会返回错误:

Incompatible types: 'TStringList' and 'TOmniValue'

我尝试过类型转换:

iniFile:= TStringList(task.Param['iniFile'].AsObject);

但是得到一个编译器错误:

F2084 Internal Error: C4310

我正在使用 OmniThreadLibrary 3.0 版 - 我无法在 D2007 中编译 3.03b

如果@gabr 是关于:伟大的工作 OmniThreadLibray,谢谢。

【问题讨论】:

  • Internal Error 是编译器中的一个错误,无论您做什么都不应该发生。编译器显然很困惑。如果你先myObject := task.Param['iniFile'].AsObject; 然后iniFile:= myObject as TStringList; 会发生什么?
  • @David Heffernan - 非常感谢,我创建了一个临时 TObject 并读取了 TOmniValue.AsObject,然后将 Tobject 类型转换为 TStringList。
  • 您的表达式要求编译器创建一个临时的本地 TOmniValue,并管理它的生命周期(它在记录中有托管类型)。这可能是导致编译器消化不良的因素。
  • 确实,您使用的是正确的方法,但编译器有问题......大卫的解决方案是正确的。升级到更现代的 Delphi 后,您还可以使用 task.Param['iniFile'].AsObject<TStringList>
  • 关于编译错误 - 我会检查发生了什么。我不再使用 D2007,并且可能会出现此类问题。

标签: delphi delphi-2007 tstringlist omnithreadlibrary


【解决方案1】:

F2084 内部错误:C4310

这是一个内部编译器错误。那是一个编译器错误。你的代码没问题,但编译器出于某种原因卡住了。

寻找解决方法。我希望编译器会因为您将数组属性读取和普通属性读取以及单个表达式中的强制转换相结合而吓坏了。您的代码没有问题,但编译器有时很容易混淆。

显而易见的尝试是为编译器提供更简单的表达式。例如,尝试存储到局部变量,然后进行强制转换:

var
  obj: TObject;
....
obj := task.Param['iniFile'].AsObject;
iniFile := TStringList(obj);

或者如果它不喜欢这样,再往前走一步:

var
  ov: TOmniValue;
  obj: TObject;
....
ov := task.Param['iniFile'];
obj := ov.AsObject;
iniFile := TStringList(obj);

或者也许你可以侥幸逃脱:

var
  ov: TOmniValue;
....
ov := task.Param['iniFile'];
iniFile := TStringList(ov.AsObject);

你应该能够让这方面的东西发挥作用。

FWIW,我建议在这里进行检查:

iniFile := ov.AsObject as TStringList;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-28
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    • 2016-07-14
    • 2010-12-08
    • 1970-01-01
    相关资源
    最近更新 更多