0

我正在使用 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 行代码。

4

1 回答 1

2

TThread::Queue()异步运行。您传递给它的方法被放入一个内部队列,然后TThread::Queue()立即退出。主 UI 线程在其最方便的时候运行 queued 方法,通常是在队列线程开始做其他事情之后很久。

您传递给的方法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);
}
于 2019-09-21T04:56:06.257 回答