TAGS :Viewed: 15 - Published at: a few seconds ago

[ Pass TStringList to TOmniTask procedure ]

I am using the OmniThreadLibrary in a Delphi 2007 app that utilises the global thread pool to preform some file operations (I need to try and make sure they are done in a specific order).

I have the contents of a newly created Ini file that is stored in a TStringList.

I then pass the TStringList to an instance of TOmniTask.

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

I cannot figure out how to retrieve the TStringList in the TOmniTask instance

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

The above would return an error:

Incompatible types: 'TStringList' and 'TOmniValue'

I have tried typecasting:

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

But get a compiler error:

F2084 Internal Error: C4310

I am using OmniThreadLibrary version 3.0 - I cant get 3.03b to compile in D2007

If @gabr is about: Great piece of work OmniThreadLibray, thank you.

Answer 1


F2084 Internal Error: C4310

This is an internal compiler error. That is a compiler bug. Your code is fine, but the compiler gags for some reason.

Look for a workaround. I expect the compiler is freaked out by your combining an array property read and a plain property read and a cast in a single expression. Nothing wrong with your code, but the compiler can sometimes be easily confused.

The obvious thing to try is to feed the compiler simpler expressions. For instance, try storing to a local variable, and then casting:

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

Or if it doesn't like that, go one step further:

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

Or maybe you can get away with:

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

You should be able to get something in this vein to work.

FWIW, I would advise a checked cast here:

iniFile := ov.AsObject as TStringList;