Stream protection in delphi

I need to modify and change some visual components in the stream, and as you know, this is not safe for this.

My question is how to write fully thread safe code? Maybe? if so please give me a simple example?

my code that is not streaming:

type tMyWorkerThread = class(TThread) public procedure Execute; override; end; var Form1: TForm1; implementation {$R *.dfm} procedure tMyWorkerThread.Execute; begin //codes //working with visual components end; procedure TForm1.Button1Click(Sender: TObject); begin TMyWorkerThread.Create(false); end; 

Thanks.

+6
source share
3 answers

My problem is resolved with Synchronize!

 type tMyWorkerThread = class(TThread) public procedure Execute; override; end; var Form1: TForm1; implementation {$R *.dfm} procedure tMyWorkerThread.Execute; begin //codes that takes long time Synchronize(procedure begin //working with visual components end ); end; procedure TForm1.Button1Click(Sender: TObject); begin TMyWorkerThread.Create(false); end; 

Thanks for helping me.

0
source

Writing a safe stream in Delphi means basic care you have in any other language, which means dealing with race conditions . A race condition occurs when different threads access the same data . A good way to handle this is to declare a TCriticalSection instance and wrap dangerous code in it.

The code below shows a getter and setter of a property that hypothesizes a race condition.

 constructor TMyThread.Create; begin CriticalX := TCriticalSection.Create; end; destructor TMyThread.Destroy; override; begin FreeAndNil(CriticalX); end; function TMyThread.GetX: string; begin CriticalX.Enter; try Result := FX; finally CriticalX.Leave; end; end; procedure TMyThread.SetX(const value: string); begin CriticalX.Enter; try FX := Value; finally CriticalX.Leave; end; end; 

Note the use of a single instance of TCriticalSection ( CriticalX ) to serialize access to an FX data element.

However, with Delphi you have an additional consideration! VCL is not thread safe, therefore, in order to avoid the VCL race conditions, any operation that results in a screen change must be performed in the main thread. You get this by calling such code inside the Sync method. Given the class above, you should do something like this:

 procedure TMyThread.ShowX; begin Synchronize(SyncShowX); end; procedure TMyThread.SyncShowX; begin ShowMessage(IntToStr(FX)); end; 

If you have Delphi 2010 or later, there is an easier way to use anonymous methods:

 procedure TMyThread.ShowX; begin Synchronize(procedure begin ShowMessage(IntToStr(FX)); end); end; 

Hope this helps!

+9
source

You should only access VCL objects from the main VCL thread.

Some read methods (getters properties) do work with other threads in practice, but you need to check their VCL sources in advance for a specific Delphi build. Or do not use it.

PS: Method synchronization starts the specified procedure in the main VCL thread, pausing the caller thread, which can lead to a deadlock if the main thread is also blocked.

More details: (in fact, for this answer to display some links)

+5
source

Source: https://habr.com/ru/post/949663/


All Articles