【发布时间】:2011-07-21 07:57:24
【问题描述】:
我使用 Borland C++Builder 6。我有一个带有表单的应用程序。应用程序/主窗体启动一个线程。 (TThread) 线程创建一个新的服务器套接字实例,并监听数据。当数据进来时,线程使用同步方法在主窗体上显示信息。
问题是,当线程发送信息时,如果单击主窗体上的菜单选项,线程执行会暂时停止。如果我在同步方法中注释掉Form1->Memo1->Lines->Add(mStr),即线程没有向主窗体发送信息,线程继续执行没有问题。所以数据被正确接收和响应。
一旦我恢复线路,并将数据写入主窗体,并在主窗体上选择了一个菜单选项,线程就会暂时停止。有没有办法阻止这种行为,使线程永远不会“阻塞”,但仍然可以向主窗体报告?
在阅读了 Martin 的回复后,我是这样做的:
在 Main.h 中:
#define WM_ADDLOG (WM_USER+0x0500)
class TForm1: public TForm
{
...
private:
void __fastcall virtual HandleAddLog(TMessage &msg);
...
public:
HWND hWnd;
TStringList *FStringBuf;
__property TStringList *StringBuf={read=FStringBuf,write=FStringBuf};
TCriticalSection tcsMsg;
...
protected:
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_ADDLOG,TMessage,HandleAddLog)
END_MESSAGE_MAP(TForm)
}
在 Main.cpp 中:
In TForm1 constructor:
...
hWnd=FindWindow(NULL,"SoftIEN");
if(!hWnd)
{
exit(0);
}
FStringBuf = new TStringList;
tcsMsg = new TCriticalSection;
...
void __fastcall TForm1::HandleAddLog(TMessage &msg)
{
String strN,strDateTime,strLine;
if(Memo1->Lines->Count>10000)
Memo1->Lines->Clear();
while(FStringBuf->Count)
{
strDateTime = "";
DateTimeToString(strDateTime, "yy/mm/dd hh:nn:ss.zzz: ", Now());
strN=FStringBuf->Strings[0];
FStringBuf->Delete(0);
strLine=strDateTime + strN;
Memo1->Lines->Add(strLine);
}
TForm::Dispatch(&msg);
}
In Thread.cpp
...
m_strMsg="Some Message";
AddLog();
...
void __fastcall TIENServerThread::AddLog()
{
Form1->tcsMsg->Acquire();
Form1->StringBuf->Add(m_strMsg);
Form1->tcsMsg->Release();
SendMessage(Form1->hWnd,WM_ADDLOG,0, 0);
}
我还在AddLog 函数中尝试了PostMessage。
一切正常,消息被写入备忘录,但当我点击主表单菜单时,应用程序仍然“冻结”。还有其他想法/帮助/示例吗?
感谢到目前为止的所有帮助!
【问题讨论】:
标签: c++ multithreading c++builder