2

assume I have a thread which is still running when the application is terminating

(This thread can not terminate because it waits for a Windows api call to return and that can be long...)

What happens to the thread if the application is closed ?

Can it raise an exception (I'm under Delphi) ?

user382591
  • 1,320
  • 5
  • 19
  • 39
  • Well, how does your application terminate? There's more than one way to do it. – David Heffernan Apr 22 '13 at 08:33
  • application.terminate; – user382591 Apr 22 '13 at 08:37
  • 1
    See also: [Thread.FreeOnTerminate := True, memory leak and ghost running](http://stackoverflow.com/q/9029730/757830). – NGLN Apr 22 '13 at 18:58
  • Which Win32 API function is your worker thread actually using? Chances are that it provides a way of canceling the function so your worker thread can terminate itself properly when requested. The main thread should be terminating the worker thread before exiting the process. – Remy Lebeau Apr 22 '13 at 22:02

1 Answers1

7

I'd say that an exception is very plausible. When you call Application.Terminate this will lead to the following sequence of events:

  1. A call to PostQuitMessage.
  2. Application.Terminated being set to True.
  3. Application.Run returning.
  4. System.Halt is called.
  5. Exit procedures are run, specifically DoneApplication which will tear down Application and all components that it owns. Hmm, better hope your thread does not access anything owned by Application.
  6. FinalizeUnits is called. Uh-oh. Memory manager is shut down, and lots more beside.
  7. ExitProcess is called. Now your thread is killed.

Your thread will carry on running until the call to ExitProcess. If it executes any code at all that would be affected by the calls to DoneApplication and FinalizeUnits, then you should expect problems.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 1
    Yes, usually because the forms, and hence the memory used by them, disappears before the OS gets the chance to stop all the threads in step 7. If you structure the app so that threads read/write directly to data in the forms, a '216' or'217' exception tends to get raised. I've, for a long time now, avoided this issue by only communicating to forms by PostMessaging objects that are not owned by forms and, usually, never explicitly freed. – Martin James Apr 22 '13 at 09:16
  • My thread does not communicate with forms. It only removes some files on a network drive (network drives can be long to be accessed...) – user382591 Apr 22 '13 at 09:35
  • @user382591 - you should be OK, then. If your thread/s are stuck on API calls, either blocked or reading/writing data that is not freed before step 7, no exception will be raised IME. – Martin James Apr 22 '13 at 09:40
  • Handles to network drives will be closed by the OS in step 7 after all your process threads have been stopped so, again, you should be OK. – Martin James Apr 22 '13 at 09:42
  • If it uses the Delphi memory manager then you are in trouble. That goes in step 6. – David Heffernan Apr 22 '13 at 09:42
  • Hmm.. does the Delphi MM explicitly free memory it has allocated in step 6? If it does, I would regard that as a bug. Locking the MM by blocking any threads that try to access it would seem to be much safer approach. – Martin James Apr 22 '13 at 09:47
  • The Thead only uses DeleteFIle and RemoveDir – user382591 Apr 22 '13 at 09:54
  • I've never seen any problem with such calls in decades of Delphi multithreaded development. I have many apps where the customers point their logging etc. paths at network drives - they work, (and shut down), fine. – Martin James Apr 22 '13 at 09:58
  • @user382591 Are the arguments to those API calls allocated on the Delphi heap? – David Heffernan Apr 22 '13 at 10:00
  • it only uses local var as arguments – user382591 Apr 22 '13 at 11:55
  • And some of those local vars could be pointers to heap allocated memory. Most likely if any of those vars are strings. Anyway, those are details for you. You have your code, we don't. I think I answered the question that you asked. – David Heffernan Apr 22 '13 at 11:56
  • Var iPath : string; iPath := 'C:\test.txt'; DeleteFile(iPath); – user382591 Apr 22 '13 at 18:18
  • If it's exactly like that, there's no heap allocation. But surely your strings are built dynamically at runtime. But have I not answered the question that you asked? – David Heffernan Apr 22 '13 at 18:22