consider following example:
t1 := ttask.run( procedure begin sleep(random(1000) + 100); raise exception.create('error message 1'); end ); t2 := ttask.run( procedure begin sleep(random(1000) + 100); raise exception.create('error message 2'); end ); res := -1; try res:= ttask.waitforany([t1, t2]); except end; write('index: ' + inttostr(res)); // prints "-1" readln;
when 1 of tasks fails waitforany throws exception , res variable not assigned index of completed task. instead contains "-1" (assigned earlier).
in c# (tpl) task.waitany
throws exception, returns index of failed task.
is there way res variable assigned or index of failed task?
you wrote:
in c# (tpl)
task.waitany
throws exception, returns index of failed task.
that's not true. consider following c# program:
using system; using system.threading.tasks; namespace consoleapplication1 { class program { static void main(string[] args) { task t1 = task.run(() => { throw new exception("task 1"); }); task t2 = task.run(() => { throw new exception("task 2"); }); int index = task.waitany(new task[] { t1, t2 }); console.writeline(index); console.readline(); } } }
both tasks throw exceptions, waitany
not. returns index value of whichever task completed first, if task threw exception.
by contrast, delphi ttask.waitforany
method raise exception if first task complete raising exception. in case, since function return values not assigned when function raises exception, need find different way identify task caused waitforany
return. instance, here rather lame way it:
{$apptype console} uses system.sysutils, system.threading; type etaskexception = class(exception) private ftaskindex: integer; public constructor create(const msg: string; const taskindex: integer); property taskindex: integer read ftaskindex; end; constructor etaskexception.create(const msg: string; const taskindex: integer); begin inherited create(msg); ftaskindex := taskindex; end; var t1, t2: itask; i, res: integer; begin t1 := ttask.run( procedure begin sleep(150); raise etaskexception.create('task failed', 0); end ); t2 := ttask.run( procedure begin sleep(100); raise etaskexception.create('task failed', 1); end ); try res := ttask.waitforany([t1, t2]); writeln('task succeeded, index ' + inttostr(res)); except on e:eaggregateexception begin := 0 e.count-1 begin writeln('task failed, index ' + inttostr((e.innerexceptions[i] etaskexception).taskindex)); end; end; end; readln; end.
although i've looped on aggregate exceptions here, believe there ever 1 inner exception waitforany
.
you may better off looping on tasks looking 1 has status
equal ttaskstatus.exception
.
Comments
Post a Comment