Передать TStringList в процедуру TOmniTask

Я использую OmniThreadLibrary в приложении Delphi 2007, которое использует глобальный пул потоков для выполнения некоторых операций с файлами (мне нужно попытаться убедиться, что они выполняются в определенном порядке).

У меня есть содержимое только что созданного файла Ini, который хранится в TStringList.

Затем я передаю TStringList экземпляру TOmniTask.

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

Я не могу понять, как получить TStringList в экземпляре TOmniTask.

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 — я не могу скомпилировать 3.03b в D2007.

Если @gabr о: Отличная работа OmniThreadLibray, спасибо.


person Gavin    schedule 19.09.2014    source источник
comment
Internal Error — это ошибка в компиляторе, и она не должна была произойти, что бы вы ни делали. Компилятор явно запутался. Что произойдет, если вы сделаете myObject := task.Param['iniFile'].AsObject;, а затем iniFile:= myObject as TStringList;?   -  person 500 - Internal Server Error    schedule 19.09.2014
comment
@David Heffernan - большое спасибо, я создал временный TObject и прочитал TOmniValue.AsObject, а затем преобразовал Tobject в TStringList.   -  person Gavin    schedule 19.09.2014
comment
Ваше выражение требует, чтобы компилятор создал временное локальное значение TOmniValue и управлял его временем жизни (у него есть управляемые типы в записи). Это, вероятно, фактор, вызывающий расстройство желудка у компилятора.   -  person David Heffernan    schedule 19.09.2014
comment
Действительно, вы используете правильный подход, но у компилятора есть проблемы... Решение Дэвида правильное. После перехода на более современную версию Delphi вы также можете выполнить task.Param['iniFile'].AsObject<TStringList>.   -  person gabr    schedule 20.09.2014
comment
Насчет ошибок компиляции - проверю, в чем дело. Я больше не пользуюсь D2007 и такие проблемы могут закрасться.   -  person gabr    schedule 20.09.2014
comment
@gabr Спасибо за ответ. Мне удалось заполучить D2010, и все работает, как задокументировано. Решение Давидса хорошо работало в D7. Еще раз, большая часть работы. Спасибо, что сделали это доступным.   -  person Gavin    schedule 10.10.2014


Ответы (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;
person David Heffernan    schedule 19.09.2014