Ivanov_G
asked on
URGENT: Problem with threads
I have input file - plain text in the format:
1
2
3
...
I use this file for open URL, submit the value as a parameter, retrieve some info and save it to file. I use a dynamic array of TMyThread type. Let's say I set its length to 30. Then loop through Low() and High() and check if the element is nil - create the thread. If it is not - check if it is running (public var in the thread). I set FreeOnTerminate = True, but somehow the thread is not nil after it finished.
I the loop if the thread has finished (it should be nil because FreeOnTerminate = True) I create a new instance. But Somehow the finished thread is not nil... I create it with CreateSuspended = False...
1
2
3
...
I use this file for open URL, submit the value as a parameter, retrieve some info and save it to file. I use a dynamic array of TMyThread type. Let's say I set its length to 30. Then loop through Low() and High() and check if the element is nil - create the thread. If it is not - check if it is running (public var in the thread). I set FreeOnTerminate = True, but somehow the thread is not nil after it finished.
I the loop if the thread has finished (it should be nil because FreeOnTerminate = True) I create a new instance. But Somehow the finished thread is not nil... I create it with CreateSuspended = False...
think abot it, you can save Thread object in number of different variables, thread could not to nil them (and even to know
about them)
but in your on destory event you can loop through your array
for (....) {
if (ThreadArr[i] = Self) then begin
ThreadArr[i] := nil;
break;
end
about them)
but in your on destory event you can loop through your array
for (....) {
if (ThreadArr[i] = Self) then begin
ThreadArr[i] := nil;
break;
end
It would actually be better to set the OnTerminate method handler for the thread, as this will run in the context of the main thread.
OnTerminate
---------------
Occurs after the thread's Execute method has returned and before the thread is destroyed.
property OnTerminate: TNotifyEvent;
Description
Write an OnTerminate event handler to execute code after the thread finishes executing. The OnTerminate event handler is called in the context of the main VCL thread, which means VCL methods and properties can be called freely. The thread object may also be freed within the event handler.
---
Regards,
Russell
ASKER
I think I have to clarify few things
type
ThreadArr : array of TMyThread;
for counter := Low(ThreadArr) to High(ThreadArr) do
begin
if ThreadArr[counter] = nil then
begin
if InputStrings.Count > 0 then
begin
ThreadArr[counter] := TMyThread.Create(False, ThreadOptions, InputStrings[0]);
InputStrings.Delete(0);
end;
end
else
if ThreadArr[counter].IsFinis hed then
begin
ThreadArr[counter].Termina te;
ThreadArr[counter] := nil;
end;
end;
This is the case here... Is finished is public variable in the thread which shows me if everything with the HTTP ended correctly...
type
ThreadArr : array of TMyThread;
for counter := Low(ThreadArr) to High(ThreadArr) do
begin
if ThreadArr[counter] = nil then
begin
if InputStrings.Count > 0 then
begin
ThreadArr[counter] := TMyThread.Create(False, ThreadOptions, InputStrings[0]);
InputStrings.Delete(0);
end;
end
else
if ThreadArr[counter].IsFinis
begin
ThreadArr[counter].Termina
ThreadArr[counter] := nil;
end;
end;
This is the case here... Is finished is public variable in the thread which shows me if everything with the HTTP ended correctly...
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Oops, posted too quick...
another example of execute without looping
procedure TMyThread.Execute;
begin
// perform first step
....
if not(Terminated) then
begin
// next step
....
if not(Terminated) then
begin
// next step
....
etc....
end;
end;
end;
----
Regards,
Russell
another example of execute without looping
procedure TMyThread.Execute;
begin
// perform first step
....
if not(Terminated) then
begin
// next step
....
if not(Terminated) then
begin
// next step
....
etc....
end;
end;
end;
----
Regards,
Russell
weird pooling scheme if it is ment to be one
for a thread pool check for example Indy's ThreadPool
the threads that finish just get suspended .. when needed nonworking threads get returned, if no thread is free a new one is created
think of something in the lines of:
while InputStrings.Count > 0 do
begin
thd:=ThreadPool.GetAvailab leThread(t rue {allow create});
thd.ProcessURL(InputString s[InputStr ings.Count -1]);
InputStrings.Delete(InputS trings.Cou nt-1);
end;
with proper locking you could make this 'live' :)
for a thread pool check for example Indy's ThreadPool
the threads that finish just get suspended .. when needed nonworking threads get returned, if no thread is free a new one is created
think of something in the lines of:
while InputStrings.Count > 0 do
begin
thd:=ThreadPool.GetAvailab
thd.ProcessURL(InputString
InputStrings.Delete(InputS
end;
with proper locking you could make this 'live' :)
ASKER
somehow ... some of the thread fails. If I run it once, it can finish successfully, but the second time, some thread will fail and this will stop the whole application...
I am trying to debug this now, but with so many threads ... grrr
I am trying to debug this now, but with so many threads ... grrr
you can nil array element in onDestroy method of your thread