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; }
source share