TThread::Queue 使 C++ Builder 崩溃

TThread::Queue crashes C++ Builder

我正在使用 C++ Builder 2010。我有一个 TThread::Synchronize 调用,它工作得很好 - 一个线程函数调用 Synchronize 并且运行良好。但是,如果我用 TThread::Queue 替换它,它会立即崩溃。

该版本的 C++ Builder 中是否存在特定错误或其他问题?

这是我用来调用主线程函数的函数:

void RunInMainThread(void(__closure *FuncToCall)(const __int64, const wchar_t), const __int64 fP1, const wchar_t fP2)
{
struct
    {
    private: typedef void(__closure *FTCdef)(const __int64, const wchar_t);

    public: __int64 P1;
            wchar_t P2;
            FTCdef  FTC;

            void __fastcall ExecFunc()
                {
                FTC(P1,P2);
                }
    } Args = { fP1, fP2, FuncToCall };

TThread::Synchronize(NULL, &Args.ExecFunc);
//TThread::Queue    (NULL, &Args.ExecFunc);
}

它调用的函数非常简单,只需用 2-3 行代码更新带有一些文本的工具栏。

TThread::Queue() 运行 异步 。你传递给它的方法被放入一个内部队列,然后 TThread::Queue() 立即退出。主 UI 线程会尽早运行排队方法,通常是在排队线程继续执行其他操作很久之后。

您传递给 TThread::Queue() 的方法属于 RunInMainThread() 的局部变量,它超出范围并且在调用排队方法时不再有效。这就是您的代码崩溃的原因。

TThread::Synchronize() 没有这个问题,因为它 同步运行 ,直到调用同步方法后才会退出。所以,使用属于局部变量的方法是可以的,在同步方法退出之前,变量不会超出范围。

要修复 TThread::Queue() 的使用,您需要动态分配变量并让主 UI 线程在排队方法完成后释放它,例如:

typedef void (__closure *FTCdef)(const __int64, const wchar_t);

void RunInMainThread(FTCdef FuncToCall, const __int64 fP1, const wchar_t fP2)
{
    struct Args
    {
        __int64 P1;
        wchar_t P2;
        FTCdef FTC;

        /*
        void __fastcall ExecFuncSync()
        {
            FTC(P1, P2);
        }
        */

        void __fastcall ExecFuncQueue()
        {
            try {
                FTC(P1, P2);
            } __finally {
                delete this;
            }
        }
    };

    //Args args{fP1, fP2, FuncToCall};
    //TThread::Synchronize(NULL, &args.ExecFuncSync);

    Args *args = new Args;
    args->P1 = fP1;
    args->P2 = fP2;
    args->FTC = FuncToCall;
    TThread::Queue(NULL, &args->ExecFuncQueue);
}