如何在没有 UI 挂起的情况下将 QtcpSockets 连接到大约 100 个服务器?
Posted
技术标签:
【中文标题】如何在没有 UI 挂起的情况下将 QtcpSockets 连接到大约 100 个服务器?【英文标题】:How can I connect QtcpSockets to about 100 servers without a UI hang? 【发布时间】:2021-06-02 06:41:31 【问题描述】:当我创建 100 个 QTcpSockets 以连接到每个服务器并调用 connectToHost() 函数时,QDialog 卡住了。有没有办法将 connectToHost() 部分作为后台作业运行?
因此,所有连接都已建立,但在尝试连接时(调用 connectToHost(),UI 处于“无响应”状态。
// onConnectToICPMC is the slot function connected to the dialog button pressed signal
void WidgetUploadFile::onConnectToICPMC()
// m_tcpClients is a QVector containing a custm QObject Class that manages QTcpSocket
for(int i = 0; i < m_tcpClients.size(); ++i)
if(m_tcpClients.at(i)->state() != QAbstractSocket::ConnectedState)
m_tcpClients.at(i)->connectToServer(); // Call the connectToHost() function of QTcpSocket.
emit sendConnProgBarUpdate(i+1);
emit sendCurrentSockLog(m_tcpClients.at(i)->ipAddress(), m_tcpClients.at(i)->state());
每个 QTcpSocket 连接到服务器时挂起的对话框。:
所有QTcpSockets尝试连接服务器后:
【问题讨论】:
最简单的解决方案可能是在循环中嵌入QApplication::processEvents()。这将在每次迭代中处理排队的事件,以便它始终仅在一次连接尝试时挂起。如果这还不够,那么您必须考虑多线程,但这可能需要更多的努力。 @Scheff'sCat 感谢您的回复。当我从另一个线程尝试 connectToHost() 时,会生成“当无法从另一个线程启用或禁用 Socket 通知程序”调试消息,所以我按照上面的代码进行编码。 【参考方案1】:耗时的任务不应该在主线程上运行。在这种情况下,有两种策略:
线程的使用。 划分子任务,每T秒分批执行一次。在这种情况下,我认为第二个选项最好使用QTimeLine
。
*.h
private:
void handleFrameChanged(int i);
QTimeLine timeLine;
*.cpp
// constructor
timeLine.setRange(0, m_tcpClients.size()-1);
connect(&timeLine, &QTimeLine::frameChanged, this, &WidgetUploadFile::handleFrameChanged);
void WidgetUploadFile::onConnectToICPMC()
timeLine.start();
void WidgetUploadFile::handleFrameChanged(int i)
auto client = m_tcpClients.at(i);
if(client->state() != QAbstractSocket::ConnectedState)
client->connectToServer();
emit sendConnProgBarUpdate(i + 1);
emit sendConnProgBarUpdate(client->ipAddress(), client->state());
【讨论】:
@eyllansec 使用 QTimer 实现,指的是如何使用您的 QTimeLine。不再有 UI 挂起。非常感谢您的想法!以上是关于如何在没有 UI 挂起的情况下将 QtcpSockets 连接到大约 100 个服务器?的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有 P/Invoke 的情况下从 c# 创建挂起的进程?
如何根据 cpu/内存使用情况或挂起的请求返回 503 服务器繁忙?