在 C++ Builder 中从其他线程调用 Timer 方法/修改属性
Call Timer methods / modify properties from other threads in C++ Builder
我正在尝试实现以下目标:从另一个线程调用方法或修改在主线程中创建的 TTimer 计时器的属性。
代码如下所示:
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Timer1->Interval = 5000;
ht=(HANDLE)_beginthread(MyThread,4096,NULL); // My Thread
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
static int i = 0;
i++;
Edit1->Text = i;
}
//---------------------------------------------------------------------------
void MyThread(void *threadparamlog)
{
// ......... My code here
Form1->Timer1->Enabled = true;
// .......... My code here
Form1->Timer1->Enabled = false;
}
可以这样直接调用吗?或者使用同步是强制性的?但是,当我尝试使用它时,出现“E2268 调用未定义函数 'Synchronize'”...
请帮忙。
Is it possible to call it like that, directly
这样做不安全。从非主 VCL 线程的线程更改主 VCL 线程中使用的 VCL 组件的状态时始终 Synchronize
。
您可以将 <System.Classes.hpp>
中的 static
TThread::Synchronize
函数与将在主 VCL 线程中执行的 lambda 函数一起使用:
void MyThread(void *threadparamlog)
{
// ......... Your code here
TThread::Synchronize(TThread::CurrentThread, // or static_cast<TThread*>(nullptr)
[]{ // a lambda function
// the code in here will be executed in the main VCL thread
Form1->Timer1->Enabled = true;
});
// .......... Your code here
TThread::Synchronize(TThread::CurrentThread, // or static_cast<TThread*>(nullptr)
[]{
Form1->Timer1->Enabled = false;
});
}
如果您的 C++ Builder 版本不支持 lambda,您可以手动构建类似的结构:
void __fastcall SetTimerEnabledValue(TTimer* timer, bool value)
{
struct ManualLambda {
TTimer* timer;
bool value;
void __fastcall SetTimerValue() {
// the code in here will be executed in the main VCL thread
timer->Enabled = value;
}
};
ManualLambda lambdaish;
lambdaish.timer = timer;
lambdaish.value = value;
TThread::Synchronize(TThread::CurrentThread, // or static_cast<TThread*>(nullptr)
&lambdaish.SetTimerValue);
}
void MyThread(void *threadparamlog)
{
// ......... Your code here
SetTimerEnabledValue(Form1->Timer1, true);
// .......... Your code here
SetTimerEnabledValue(Form1->Timer1, false);
}
我正在尝试实现以下目标:从另一个线程调用方法或修改在主线程中创建的 TTimer 计时器的属性。
代码如下所示:
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Timer1->Interval = 5000;
ht=(HANDLE)_beginthread(MyThread,4096,NULL); // My Thread
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
static int i = 0;
i++;
Edit1->Text = i;
}
//---------------------------------------------------------------------------
void MyThread(void *threadparamlog)
{
// ......... My code here
Form1->Timer1->Enabled = true;
// .......... My code here
Form1->Timer1->Enabled = false;
}
可以这样直接调用吗?或者使用同步是强制性的?但是,当我尝试使用它时,出现“E2268 调用未定义函数 'Synchronize'”... 请帮忙。
Is it possible to call it like that, directly
这样做不安全。从非主 VCL 线程的线程更改主 VCL 线程中使用的 VCL 组件的状态时始终 Synchronize
。
您可以将 <System.Classes.hpp>
中的 static
TThread::Synchronize
函数与将在主 VCL 线程中执行的 lambda 函数一起使用:
void MyThread(void *threadparamlog)
{
// ......... Your code here
TThread::Synchronize(TThread::CurrentThread, // or static_cast<TThread*>(nullptr)
[]{ // a lambda function
// the code in here will be executed in the main VCL thread
Form1->Timer1->Enabled = true;
});
// .......... Your code here
TThread::Synchronize(TThread::CurrentThread, // or static_cast<TThread*>(nullptr)
[]{
Form1->Timer1->Enabled = false;
});
}
如果您的 C++ Builder 版本不支持 lambda,您可以手动构建类似的结构:
void __fastcall SetTimerEnabledValue(TTimer* timer, bool value)
{
struct ManualLambda {
TTimer* timer;
bool value;
void __fastcall SetTimerValue() {
// the code in here will be executed in the main VCL thread
timer->Enabled = value;
}
};
ManualLambda lambdaish;
lambdaish.timer = timer;
lambdaish.value = value;
TThread::Synchronize(TThread::CurrentThread, // or static_cast<TThread*>(nullptr)
&lambdaish.SetTimerValue);
}
void MyThread(void *threadparamlog)
{
// ......... Your code here
SetTimerEnabledValue(Form1->Timer1, true);
// .......... Your code here
SetTimerEnabledValue(Form1->Timer1, false);
}