【发布时间】:2015-10-21 09:52:02
【问题描述】:
我正在 C++ Builder XE2 中开发所谓的“feeder”应用程序,它使用 2 个内置的 Indy 组件 - TIdTCPClient 和 TIdTCPSever。 TIdTCPClient 用于从一个源接收数据,形成字符串消息,然后使用 TIdTCPSever 将此字符串消息发送到所有客户端应用程序。对于数据重新翻译,我使用下一个函数(idEventsServerSocket 是 TIdTCPSever 组件):
void TfrmMainWindow::SendDataToAllClients(String msg) {
TList *ClientsList;
try
{
ClientsList = idEventsServerSocket->Contexts->LockList();
for (int i = 0; i < ClientsList->Count; i++) {
TIdContext *Context = (TIdContext*)ClientsList->Items[i];
bool connected = false;
try {
connected = Context->Connection->Connected();
}
catch (Exception&e) {
continue;
}
if (!connected)
continue;
try {
Context->Connection->IOHandler->WriteLn(msg);
Context->Connection->IOHandler->WriteBufferFlush();
}
catch (Exception&e) {
}
}
}
__finally
{
idEventsServerSocket->Contexts->UnlockList();
}
}
我还想注意这个函数包含在 EnterCriticalSection ... LeaveCriticalSection 代码段中,所以应该保证在函数没有执行之前不会有新的进入这个函数代码。对于 idEventsServerSocket,定义了 OnException 和 OnListenException 处理程序并包含空代码。
所以问题是:有时行
ClientsList = idEventsServerSocket->Contexts->LockList();
导致应用程序挂起。当它发生时没有一般规律,但看起来它在大多数时候发生,当函数 SendDataToAllClients 被非常频繁地调用(比如每 10 到 50 毫秒一次)。客户端连接数从 30 到 50 不等。 我需要知道的是,有什么办法可以避免这种僵局?我有任何检查(如 TryEnterCriticalSection)吗? 另外我想承认Delphi: TThreadList sometimes lock program 的 Remy 解决方案没有帮助。
【问题讨论】: