I realise this is an old post...
The other thing - usually with COM, you need to CoInitialize() in each thread, and if you are a nice citizen, CoUninitialize().
To coordinate shutdown, you may also want to look at TCountdownEvent from System.SyncObjs. TCountdownEvent waits for a counter to reach zero. A signal in a thread would trigger the countdown.
Could do something like (sorry, I automatically referenced TTask.Run rather than Parallel.Async)
// This is pseudocode, so might not be 100% accurate with params
var event := TCountdownEvent.Create();
event.AddCount(length(workList));
for var work in workList do
begin
TTask.Run(procedure
begin
CoInitialize();
try
process(work);
finally
CoUninitalize();
event.signal();
end;
end;
end;
event.WaitFor(INFINITE);
With the above code, if run from a UI would still block, so that should also be threaded if the UI is meant to remain responsive.