Both options are possible.
1- try do destroy the objects
If you want to speculatively call a routine inside the DLL you'll have to put it inside a separate thread. put the mean thread to sleep and if the call does not return within the stated time assume that it hung.
2- just end the program
Windows will clear up all memory and GDI objects that a program used when it is terminated.
If you have open files where data has not been flushed out, lose data there, so depending on the nature of the application this may be a bad idea.
Here's how to do the cleanup in a separate thread:
interface
....
TCleanUpThread = class(TThread)
procedure Execute; override;
end;
implementation
procedure TCleanUpThread.Execute;
var
Status: integer;
begin
Status:= FirstDllCleanUp;
LogProgress('first cleanup is done, statuscode: '+IntToStr(Status));
Status:= SecondDllCleanUp;
LogProgress('Second cleanup is done, statuscode: '+IntToStr(Status));
....
end;
procedure TForm1.TryCleanup;
const
StartNow = false;
var
CleanUpThread: TCleanUpThread;
begin
CleanUpThread:= TCleanUpThread.Create(StartNow);
Sleep(1000); // wait a while to see if clean exit occurs
if not(CleanUpThread.Terminated) then begin
//Take measures if needed, depending on the logged data.
end;
end; //Continue with the shutdown from here.
Warning
Note that you cannot call synchronize
or your thread will not run in parallel anymore.
Also note that you cannot more thread unsafe calls in your code.
All of GDI and all user interface stuff is out, those need to be handled in the main thread (i.e. the program itself).