I am using thread wrapper which checks if function which updates VCL (which also has some arguments) was called from main thread or not and then executes in within the context of Main thread always.
It works but I want to make it simpler. The problem is that I have to repeat this code in every function which needs VCL synchronization which is prone to errors. Is there a way to make this wrapper simpler and more re-useable? Note that this particular wrapper only uses one parameter but there can be any number of parameters which are copied to TLocalArgs
and passed on.
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;
}