Root > Advanced topics > Multi-threaded applications > Creating threads > BeginThreadEx Function

BeginThreadEx Function

Previous pageReturn to chapter overviewNext page   

Important: as a general rule, you should write your application in a such way that it will behave correctly without EurekaLog on board. This means that if your or 3rd party code throws an exception in a thread - it must be handled in a way that you expect. For example, by showing an error message, canceling action, retrying, etc. Once your application behaves like it is supposed to do - then you add EurekaLog for it. EurekaLog will auto-handle all unhandled exceptions automatically (by hooking few well-known places), and for everything else - you can call EurekaLog from your own handlers when needed. In other words:

Incorrect: your application does not show messages for exceptions in thread and you are adding EurekaLog in hopes to fix this behavior;
Correct: your application correctly handles thread exceptions and you are adding EurekaLog to receive reports about such exceptions.


EurekaLog provides two helper routines to simplify thread management: BeginThreadEx function and TThreadEx class - which should be used instead of BeginThread function and TThread class respectively. Both routines are from EBase unit. EBase unit is a special unit that can be included in any application without including full EurekaLog code. Therefore you can safely use EBase unit in your applications even without EurekaLog enabled.


Note: when your thread is processing exception, the processing will be performed in a background thread. EurekaLog's event handlers will be called from a background thread. You need to use some sort of synchronization if you are accessing global data in your EurekaLog's event handlers. This also means that several threads can process multiple exceptions simultaneously at the same time. You can avoid this by marshaling processing to main thread. For example, you can use TThread(Ex) and analyze .FatalException property in your main thread. See description of TThreadEx class for examples. Alternatively, you may use "Consecutive processing" option.


Both BeginThreadEx function and TThreadEx class offers two additional arguments:

Thread name;
EurekaLog's state.


Note: the EurekaLog's state will be ignored if you compile your application without EurekaLog (or with disabled EurekaLog). On the other hand, the thread name is never ignored. Thread name is used by debugger to show thread's name in Threads window.


Thread name is arbitrary text string which can contain any combination of characters. Thread name will be shown in debugger (Threads window) and it will be used as thread caption in bug reports. You can use thread name to identificate threads.


Example of using BeginThreadEx function for this sample code:


function ThreadFunc(Parameter: Pointer): Integer;
  // No additional code needed inside thread func

  // <- ... your code for the thread ...

  Result := 0; // to indicate "success"
procedure TForm1.Button1Click(Sender: TObject);
  TID: Cardinal;
  // This code ignores any failures in thread, but
  // you may want to use GetExitCodeThread function.
  CloseHandle(BeginThreadEx(nil, 0, ThreadFunc, nil, 0, TID,

    // New argument: thread name
    'This is my thread with Parameter = ' + 
      IntToHex(NativeUInt(nil), SizeOf(Pointer) * 2)));


This code sample works exactly as the previous code sample. You can pass thread name right into BeginThreadEx function. Thread will be automatically named - regardless of EurekaLog's state.


Threads launched with BeginThreadEx will be EurekaLog-enabled by default. You can supply optional Boolean argument for BeginThreadEx function to disable EurekaLog in thread, for example:


BeginThreadEx(nil, 0, ThreadFunc, nil, 0, TID, 'Thread Name', False { disable EurekaLog in thread } );



Thread function for BeginTheadEx function has the same signature (prototype) as thread function for BeginThread function. I.e. you don't have to change thread function declaration.
BeginThreadEx function has almost the same signature (prototype) as BeginThread function: the only difference is two additional arguments, which are optional. This means that you can just add "Ex" suffix to your existing BeginThread calls.
There is no need to wrap thread function for BeginThreadEx into explicit try/except block - as you do this for thread function from BeginThread function. BeginThreadEx always protect thread function with exception handling block with a call to default exception handler - regardless of EurekaLog's state in this thread and your application. Any exception in thread created with BeginThreadEx function will be handled by default handler - showing either error message (if EurekaLog is not enabled) or full bug report dialog (if EurekaLog is enabled), and thread exit code will be non-zero, application will not be terminated. Use explicit try/except block if you want some custom processing for exceptions (for example, if you want to terminate application after handling exception from background thread). This also means that both thread functions (with and without try/except blocks) are fully compatible with BeginThreadEx function.
The above facts mean that BeginThreadEx function is fully source-compatible with BeginThread function. Therefore, you can do a search&replace "BeginThread" -> "BeginThreadEx" over all source files for your project. This is a quick way to manually enable EurekaLog for your threads. The same is true for TThread -> TThreadEx.
BeginThreadEx function does not terminate application when thread exception is raised.
Thread will return non zero exit code when there was exception in this thread. Otherwise (i.e. if there was no exception in the thread) - the exit code will match result of the thread function (usually - zero). This can be used to get "success/failure" exit status of the thread - via GetExitCodeThread function.



See also:

Send feedback... Build date: 2023-09-11
Last edited: 2023-03-07
The documentation team uses the feedback submitted to improve the EurekaLog documentation. We do not use your e-mail address for any other purpose. We will remove your e-mail address from our system after the issue you are reporting has been resolved. While we are working to resolve this issue, we may send you an e-mail message to request more information about your feedback. After the issues have been addressed, we may send you an email message to let you know that your feedback has been addressed.

Permanent link to this article: