Simplify VCL Stream Shell Code

I use thread wrapper, which checks if a function updating VCL (which also has some arguments) was called from the main thread or not, and then it was always executed inside the Main thread context.

This works, but I want to make it easier. The problem is that I have to repeat this code in every function that needs VCL synchronization, which is error prone. Is there a way to make this shell simpler and more reusable? Please note that in this particular shell only one parameter is used, but there can be any number of parameters that are copied to TLocalArgs and transferred.

Current code:

 boost::scoped_ptr<TIdThreadComponent> WorkerThread; ... void TForm1::SetMemoMessage(UnicodeString Msg) { // Check which thread called function, main thread or worker thread if (GetCurrentThreadId() != System::MainThreadID) { struct TLocalArgs { TForm1 *Form; UnicodeString Msg; void __fastcall SetMemoMessage() // Same name as main function to make it easier to maintain { // We are in main thread now, safe to call message update directly Form->SetMemoMessage(Msg); } }; // We are in worker thread, wrap into Synchronize TLocalArgs Args = { this, Msg }; WorkerThread->Synchronize(&Args.SetMemoMessage); return; } // MAIN THREAD CODE is very simple compared to wrapper above Memo1->Text = Msg; } 
+3
source share
1 answer

TThread::Synchronize() checks MainThreadID internally for you and calls the specified procedure directly if Synchronize() is called from the main thread. So just call Synchronize() unconditionally and let it handle the details. Synchronize() also has overloaded static versions, so you don’t even need a TThread pointer to call it.

Try the following:

 void TForm1::SetMemoMessage(UnicodeString Msg) { struct TLocalArgs { UnicodeString Msg; void __fastcall SetMemoMessage() { Form1->Memo1->Text = Msg; } }; TLocalArgs Args; Args.Msg = Msg; TThread::Synchronize(NULL, &Args.SetMemoMessage); } 
+5
source

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


All Articles