Solved

How to check whether Thread is running? (D7)

Posted on 2011-09-28
13
1,546 Views
Last Modified: 2012-05-12
After
MyThread.Terminate;
MyThread.WaitFor;
MyThread.Free;

WaitForSingleObject(MyThread.Handle, 0)<>WAIT_OBJECT_0
and MyThread<>nil still return True.
Is there any other way to check whether Thread is running?
0
Comment
Question by:3axap
  • 6
  • 6
13 Comments
 
LVL 12

Expert Comment

by:Hypo
ID: 36813927
Hi,
So, after you've called MyThread.Free, you must not use that object anymore, since free triggers the deallocation of the memory for that object, that memory area that used to belong to the object might now be used by other objects and functions...

When you execute WaitForSingleObject(MyThread.Handle, 0); after you've freed the MyThread object, that handle you pass to the function is no longer valid, since the thread has been released... so that might be the reason why you get the unexpected result...

If you want to check that the thread has actually finished using WaitForSingleObject, you shall do that check before you free the MyThread object... also when you free the object I suggest you start using the function FreeAndNil, so that you don't keep pointers to objects that have been deallocated.

MyThread.Terminate;
MyThread.WaitFor;
// Check if the thread has actually terminated...
If WaitForSingleObject(MyThread.Handle, 0)<>WAIT_OBJECT_0 then ... ;
// Free the thread and set it's pointer to nil...
FreeAndNil(MyThread);


/Hypo
0
 

Author Comment

by:3axap
ID: 36815492
Actually, I'd like to be sure that thread is terminated.
When thread is running WaitForSingleObject(MyThread.Handle, 0)<>WAIT_OBJECT_0 returns True and after I terminated and freed it WaitForSingleObject(MyThread.Handle, 0)<>WAIT_OBJECT_0 still returns True.
That is where I'm lost. I thought it should return False.

MyThread.Terminate; sets a flag for the thread to finish its routine and stop. But sometimes MyThread is hanging up and I want to set a timer to let it finish and if not use TerminateThread(MyThread.ThreadID, 0);
0
 
LVL 12

Expert Comment

by:Hypo
ID: 36815518
The thing is that if you free the thread, then you cant check if it's still running, because once you call MyThread.Free, the handle to the thread becomes invalid... and you need a valid handle for the WaitForSingleObject call...

That is what I tried to explain, If you need to check if the thread is still running, you need to do that before you call MyThread.free...

/Hypo
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 

Author Comment

by:3axap
ID: 36815521
I can rephrase my question if I may.
How to get confirmation that thread I want to terminate is actually terminated?
0
 
LVL 12

Accepted Solution

by:
Hypo earned 500 total points
ID: 36815635
Your example with WaitForSignleObject should actually work fine... but as I said, you can not use that function after you have called MyThread.Free, so you must place WaitForSingleObject before MyThread.Free.

i.e.

if WaitForSingleObject(MyThread.Handle, 0) <> WAIT_OBJECT_0 then ... // If True the thread is still active
...
MyHandle.Free;


Another thing you can try, is to use the function GetExitCodeThread.

i.e.
var aExitCode : Cardinal;
...
if not GetExitCodeThread(MyThread.Handle, aExitCode) then
  raiseLastOsError;  
if aExitCode = STILL_ACTIVE then ...; // If true, your thread is still active...

In either case, you can not do these tests after MyThread.Free has been called.

if you want to force/kill your thread there is a function called TerminateThread, that works in the same way as GetExitCodeThread... but you should be aware of that this methods stops the thread directly, and may lead to the thread not being able to free it's resources (e.g. high possibility of memory leakage) ...

/Hypo
0
 
LVL 12

Expert Comment

by:Hypo
ID: 36815672
sorry, typo in my last post...

MyHandle.Free should actually be MyThread.Free...

/Hypo
0
 
LVL 21

Expert Comment

by:developmentguru
ID: 36816672
You can also assign your thread on OnTerminate event.  This will call your code when the thread is terminated.  This previously answered question demonstrates using OnTerminate with multiple threads.

http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_27317530.html
0
 

Author Comment

by:3axap
ID: 36890510
I checked GetExitCodeThread.
Could you please revise my code below.
Thanks.

procedure mainForm.ThrdTerminate;
var
  aExitCode: Cardinal;
begin
  MyThread.Terminate;
  WaitForSingleObject(MyThread.Handle, 10000);
  if not GetExitCodeThread(MyThread.Handle, aExitCode) then raiseLastOsError;
  if (aExitCode=STILL_ACTIVE) then TerminateThread(MyThread.ThreadID, 0) 
  	else MyThread.Free;
end;

Open in new window

0
 
LVL 12

Expert Comment

by:Hypo
ID: 36890541
I would add one change to your code, and that is to always free at the end... but in large it looks ok...

However, If you are having problems with your thread not being terminated when you request it with MyThread.Terminate, that indicates that you have something wrong in your thread that you ought to correct... because as I said in an earlier post, when you force a thread to terminate using TerminateThread, there is a high risk of memory leakage, and you should avoid using it if possible...

Are you perhaps doing any Synchronize calls in your thread, or any other calls to WaitForSingleObject where you wait for Events, Mutexes or Semaphores to be signaled? because that might be the reason why your thread isn't always terminating properly.


procedure mainForm.ThrdTerminate;
var
  aExitCode: Cardinal;
begin
  MyThread.Terminate;
  WaitForSingleObject(MyThread.Handle, 10000);
  if not GetExitCodeThread(MyThread.Handle, aExitCode) then raiseLastOsError;
  if (aExitCode=STILL_ACTIVE) then TerminateThread(MyThread.ThreadID, 0);
  FreeAndNil(MyThread);
end;

Open in new window


/Hypo
0
 

Author Comment

by:3axap
ID: 36890962
I'm trying to find solution for thread also. It just that InternetOpenUrl in thread is hanging if server on the other side is down. I'll use TerminateThread only when terminate application.
0
 
LVL 12

Expert Comment

by:Hypo
ID: 36890999
Ok, so there is no timeout that can be set for that function?

Perhaps you already know this, but there is one function you can use to test if you can connect to a server called InternetCheckConnection... have you tried calling that one before you call InternetOpenUrl?

/Hypo
0
 

Author Comment

by:3axap
ID: 36891116
I thought InternetCheckConnection is telling whether I'm connected to the Internet.
I'll look at it. Thanks.
0
 

Author Closing Comment

by:3axap
ID: 36891122
Thanks a lot.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Comparing dates in Delphi. Greater than/ Less than 3 225
Delphi 2 69
can't find the executable in Simulator 1 101
How to Get Images From Server using App Tethering 11 40
A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…

821 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question