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);
}
我正在使用 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);
}