如何在 TIdTCPServer::Execute 中同步代码
How To Sychronize Code In TIdTCPServer::Execute
我在 TIdTCPServer::Execute 方法中有 VCL 代码需要同步,我该怎么做?
void __fastcall Tdata::bcServerExecute(TIdContext *AContext)
{
String json = AContext->Connection->Socket->ReadLn();
TJSONObject* jo = (TJSONObject*)TJSONObject::ParseJSONValue(json);
if (jo != 0)
{
TJSONPair* jp = (TJSONPair*)jo->Get("text");
String text = jp->JsonValue->Value();
jp = (TJSONPair*)jo->Get("font_size");
int font_size = _wtoi(jp->JsonValue->Value().c_str());
int tw = 0;
double text_width = 0.0;
//================================
TCanvas* canvas = new TCanvas();
if (canvas)
{
canvas->Handle = GetDC(0);
canvas->Font->Size = font_size;
tw = canvas->TextWidth(text);
double ppi = Screen->PixelsPerInch;
text_width = double(tw) / ppi;
ReleaseDC(0,canvas->Handle);
delete canvas;
}
String buf = String(text_width);
//==================================
AContext->Connection->IOHandler->WriteLn(buf);
}
}
代码周期性死锁不足为奇。
此代码中的任何内容都不需要通过 Synchronize 委托给主 UI 线程。
但是,当在工作线程中使用 TCanvas
时,您确实需要在使用它时 Lock()
它,否则主 UI 线程会干扰它后台(更新: 具体来说,主要 UI 线程经常释放 HDC
属于 unlocked TBitmap.Canvas
和 TControlCanvas
对象,甚至是工作线程正在使用的对象。不过,如果您使用 TCanvas
本身就可以了。
或者,只需将 TCanvas
替换为相应的 Win32 API 函数调用 (CreateFontIndirect()
, GetTextExtentPoint32()
),那么您就不必担心锁定任何内容。
我在 TIdTCPServer::Execute 方法中有 VCL 代码需要同步,我该怎么做?
void __fastcall Tdata::bcServerExecute(TIdContext *AContext)
{
String json = AContext->Connection->Socket->ReadLn();
TJSONObject* jo = (TJSONObject*)TJSONObject::ParseJSONValue(json);
if (jo != 0)
{
TJSONPair* jp = (TJSONPair*)jo->Get("text");
String text = jp->JsonValue->Value();
jp = (TJSONPair*)jo->Get("font_size");
int font_size = _wtoi(jp->JsonValue->Value().c_str());
int tw = 0;
double text_width = 0.0;
//================================
TCanvas* canvas = new TCanvas();
if (canvas)
{
canvas->Handle = GetDC(0);
canvas->Font->Size = font_size;
tw = canvas->TextWidth(text);
double ppi = Screen->PixelsPerInch;
text_width = double(tw) / ppi;
ReleaseDC(0,canvas->Handle);
delete canvas;
}
String buf = String(text_width);
//==================================
AContext->Connection->IOHandler->WriteLn(buf);
}
}
代码周期性死锁不足为奇。
此代码中的任何内容都不需要通过 Synchronize 委托给主 UI 线程。
但是,当在工作线程中使用 TCanvas
时,您确实需要在使用它时 Lock()
它,否则主 UI 线程会干扰它后台(更新: 具体来说,主要 UI 线程经常释放 HDC
属于 unlocked TBitmap.Canvas
和 TControlCanvas
对象,甚至是工作线程正在使用的对象。不过,如果您使用 TCanvas
本身就可以了。
或者,只需将 TCanvas
替换为相应的 Win32 API 函数调用 (CreateFontIndirect()
, GetTextExtentPoint32()
),那么您就不必担心锁定任何内容。