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

CreateThread 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.

 

CreateThread system function is a basic function to create any thread. Any other method for creating threads is based on CreateThread function.

 

Warning: it is not recommended to directly use CreateThread function in your application. Always use at least BeginThread function instead of CreateThread function - however, it is recommended to use BeginThreadEx function instead of CreateThread. BeginThread(Ex) functions contain RTL thread support code.

 

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.

 

Thread function for CreateThread is not protected by any exception handler. Any exception in thread created with CreateThread function will terminate the application:

Under debugger: debugger will show "Project ... faulted with message ..." notification and terminate the application.
Free run: system will show "... has stopped working. A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available" error dialog and terminate the application.

 

EurekaLog will install wrapper for any CreateThead's thread function to catch unhandled exceptions in threads (as long as "Use low-level hooks" option is enabled and corresponding threading option is set). Therefore you don't need to write any additional code if you're going to always use EurekaLog in your applications. EurekaLog will show a usual EurekaLog error dialog with full bug report and terminate the application.

 

Important note: EurekaLog has to be enabled for background threads.

 

Important note: turning off low-level hooks means that EurekaLog will not install additional hooks for API functions. This means that EurekaLog will not intercept important system calls. For example, EurekaLog will not hook ExitThread function, which means EurekaLog will not know when a thread exits. This will lead to thread information stored forever - until application terminates. You can call internal _NotifyThreadGone or _CleanupFinishedThreads functions (from EThreadsManager unit) to notify EurekaLog about thread's termination. Such manual notifications can be avoided by using EurekaLog's wrappers (TThreadEx, for example).

 

However, if you want to compile your application with and without EurekaLog (for example, as release/debug builds) or if you don't want to install low-level hooks (for better compatibility with external tools) - then you have to wrap each thread function into explicit try/except block like this:

 

function ThreadFunc(Parameter: Pointer): Integer; stdcall;
begin
  try
    // 1. Name the thread for easy identification in debugger and bug reports
    NameThread('This is my thread');

 
    // 2. Activate EurekaLog for this thread.
    SetEurekaLogStateInThread(0, True); 
 
    // 3. <- ... your code for the thread ...

 
    Result := 0; // to indicate "success" 
 
  except
 
    // Handle any exception in thread
    ApplicationHandleException(nil); // from Classes unit
    Result := 1; // to indicate "failure"
 
  end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  TID: Cardinal;
begin

  // This code ignores any failures in thread, but

  // you may want to use GetExitCodeThread function.

  IsMultiThreaded := True;
  CloseHandle(CreateThread(nil, 0, @ThreadFunc, nil, 0, TID));

end;

 

Note: while most calls to VCL are not thread-safe, ApplicationHandleException function is a default global exception handler. This function is called to handle exceptions by multi-threaded applications. Therefore, this function is thread-safe. Alternative approach is to use HandleException function from EBase unit. HandleException function will show standard error dialog if EurekaLog was not enabled. HandleException function will show EurekaLog error dialog if EurekaLog was enabled. EBase unit is a special unit that can be included in any application without including full EurekaLog code. See also: how to handle an exception.

 

This code sample will gracefully handles any exception in thread - regardless if EurekaLog is enabled for application or not:

EurekaLog is enabled: this sample will show usual EurekaLog's error dialog with full bug report;
EurekaLog is not enabled: this sample will show error message in message box.

 

Important note: EurekaLog has to be enabled for background threads.

 

Warning: it is not recommended to directly use CreateThread function in your application. Always use at least BeginThread function instead of CreateThread function - however, it is recommended to use BeginThreadEx function instead of CreateThread. BeginThread(Ex) functions contain RTL thread support code.

 

 

See also:




Send feedback... Build date: 2023-09-11
Last edited: 2023-07-12
PRIVACY STATEMENT
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: https://www.eurekalog.com/help/eurekalog/multithreading_createthread.php