简化VCL线程包装器代码

Cod*_*345 3 multithreading vcl synchronization c++builder

我正在使用线程包装器,它检查是否从主线程调用更新VCL(也有一些参数)的函数,然后在主线程的上下文中执行.

它有效,但我想让它变得更简单.问题是我必须在需要VCL同步的每个函数中重复此代码,这很容易出错.有没有办法让这个包装器更简单,更可重用?请注意,此特定包装器仅使用一个参数,但可以有任意数量的参数复制TLocalArgs并传递.

当前代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

Rem*_*eau 6

TThread::Synchronize()MainThreadID内部检查并直接调用指定的过程,如果Synchronize()从主线程调用.所以只要Synchronize()无条件地打电话,让它处理细节. Synchronize()也有重载的静态版本可用,所以你甚至不需要一个TThread指针来调用它.

试试这个:

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);
}
Run Code Online (Sandbox Code Playgroud)