2017-01-17 2 views
1

Qt 5.7.1에서 람다 및 타이머와 이상한 동작이 있습니다. 아마 나 한테 실수 한거야.QLocalSocket - QTimer 및 Lambda

소켓과의 연결을 시작하고 일정 시간이 지난 후에 소켓이 연결되었는지 여부를 확인하는 타이머를 설정합니다.

소켓에 연결된 신호가 시간을 멈 춥니 다.

그러나 다음 구현에서는 연결된 신호가 호출 되더라도 타이머가 중지되지 않습니다.

client connecting. . . 
client connected 
server got connection 
client connection timed out 

나는 또한 항상 재현이 아니다 발견과 : 여기

constructor: 

m_connectTimeout.setInterval(5000); 

connect(&m_socket, &QLocalSocket::connected, [&]() 
{ 
    // this is called first and should stop the timer. 
    m_connectTimeout.stop(); 
}); 


connect(&m_connectTimeout, &QTimer::timeout, [&](){ 
     // this is still called 
}); 

는 Qt5.7.1 및 Windows 10 프로그램의

#include <QtCore> 
#include <QtNetwork> 

#define PIPENAME "testbug" 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 

    QTimer timer; 
    QLocalSocket socketClient, *socketServer; 
    QLocalServer server; 
    timer.setInterval(2000); 


    QObject::connect(&timer, &QTimer::timeout, [&] 
    { 
     qDebug() << "client connection timed out"; 
     timer.stop(); 
    }); 

    QObject::connect(&socketClient, &QLocalSocket::connected, [&] 
    { 
     qDebug() << "client connected"; 
     timer.stop(); 
    }); 

    QObject::connect(&server, &QLocalServer::newConnection, [&] 
    { 
     qDebug() << "server got connection"; 
     socketServer = server.nextPendingConnection(); 
    }); 

    server.setSocketOptions(QLocalServer::WorldAccessOption); 
    server.listen(PIPENAME); 

    qDebug() << "client connecting. . ."; 
    socketClient.connectToServer(PIPENAME, QLocalSocket::ReadWrite); 
    timer.start(); 

    return a.exec(); 
} 

출력에 재현 문제와 최소한의 예입니다 어떻게 든 무작위로 보인다.

+0

'''m_connectTimeout.stop()'''실제로 실행됩니까? 중단 점 설정 및 실행 여부 확인 –

+1

[MCVE] (https://stackoverflow.com/help/mcve)를 제공하십시오. 나는'm_connectTimeout.stop()'이 타이머를 멈추지 않는 이유를 생각할 수 없다. 다음은 문제를 재현하지 않는 [최소 예] (https://gist.github.com/micjabbour/292d14219a20ef00f8d4d1e332916b5c)입니다. – Mike

+0

@ 빅터, 예, 실행됩니다. 실제로 거기에 디버그 출력이 있습니다. – Damien

답변

1

실제로 코드가 작동하는 것처럼 보입니다. 연결이 너무 빠르기 때문에 timer.stop이 timer.start보다 먼저 호출됩니다. 서버에 연결 호출하기 전에 타이머를 시작

도 전에, 슬롯 호출 할 수 있도록이 connectToServer 백그라운드에서 이벤트 루프에 어떤 통화를한다는 것을 의미 할 것입니다 문제를

m_timer.start(); 
m_socketClient.connectToServer(PIPENAME, QLocalSocket::ReadWrite); 

를 해결하는 것 다음 행이 실행됩니다.

+0

예, 그게 문제입니다. 답변을 쓰고있었습니다. . 'connected()'신호는'connectToServer()'내부에서 방출되고 타이머는 슬롯에서 정지 된 후에 시작됩니다. – Mike