I have developed an application that connects to SQL Server database and reads some data from tables every 1 second.
For this purpose I use TTimer but the delay of the database response affects my application performance.
I know a little about TThread in Delphi, what I want to know now is the difference between using TTimer and TThread? And using TThread instead of TTimer is useful for my application performance in this case?
The timer isn't a thread BUT having a timer fire events asynchronously can be regarded as a form of multi-threading - along with all the traditional multi-threading issues!
The Timer is a subclass of Thread. Timer class represents an action that should be run only after a certain amount of time has passed. A Timer starts its work after a delay, and can be canceled at any point within that delay time period. Timers are started, as with threads, by calling their start() method.
Timer is not thread-safe.
The main difference between the two can be found in their class definition:
TTimer = class(TComponent)
TThread = class
While the TTimer class extends TComponent and is a component itself, TThread is an abstract class which extends TObject.
TThread exposes static methods like TThread.Sleep and a peculiar protected method called Execute which must be implemented in the derived class in order to perform the desired job.
TThread directly uses the Processes and Threads functions of the guest OS.
... for this purpose I use
TTimerbut the delay of Database response affect on my application performance
The reason why this happens is because the OnTimer event of the TTimer object is executed in the calling thread: when a TTimer component is put into a form and its OnTimer event is implemented, the code is executed in the main thread.
The TThread approach is more flexible: if for some reason the code must be performed in the main thread, this can be achieved nesting a sinchronized block inside the thread's Execute method.
If you want to execute database requests in a repeated manner after some time interval, you better consider using a TThread in combination with a TEvent object.
An example of class definition using TEvent:
TMyThread = class(TThread)
private
FInterval: Integer;
FWaitEvent: TEvent;
protected
procedure Execute; override;
procedure TerminatedSet; override;
public
constructor Create(Interval: Cardinal; CreateSuspended: Boolean);
destructor Destroy; override;
end;
The implemented class:
constructor TMyThread.Create(Interval: Cardinal; CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
FInterval := Interval;
FWaitEvent := TEvent.Create(nil, False, False, '');
end;
destructor TMyThread.Destroy;
begin
FWaitEvent.Free;
inherited;
end;
procedure TMyThread.TerminatedSet;
begin
inherited;
FWaitEvent.SetEvent;
end;
procedure TMyThread.Execute;
begin
inherited;
while not Terminated do begin
//do your stuff
//wait fo some amount of time before continue the execution
if wrSignaled = FWaitEvent.WaitFor(FInterval) then
Break;
end;
end;
The WaitFor method called on the FWaitEvent object allows to wait for the desired amount of time.
The implementation of the thread's TerminatedSet method allows to put the FWaitEvent object in a signaled state and then exit from the thread before the interval has elapsed.
TTimer is a message-based timer. It posts WM_TIMER messages to the message queue of the thread that creates it. Your database operations are blocking that thread from processing new messages in a timely manner. Assuming your TTimer is in the main UI thread, that is why your app performance suffers. Moving the database operations into a worker thread prevents the main thread's message loop from being blocked.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With