2017-01-17 10 views
1

Qt 5.7.1でLambdaとタイマーで奇妙な動作があります。おそらく私の間違いでしょう。QLocalSocket - QTimerとLambda

ソケットとの接続を開始し、一定時間後に接続されているかどうかを確認するタイマーを設定します。

ソケットの信号が接続されている時間が停止します。

ただし、次の実装では、接続された信号が呼び出されてもタイマーは停止しません。ここで

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 
}); 

プログラムの問題

#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(); 
} 

Qt5.7.1およびWindows 10上で再現可能な出力を持つ最小の例である:私もそれは常に再現可能ではありません気付い

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

と何とかランダムなようです。

+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