0

を操作しているときに問題が発生しJFrame、コードを継続的に実行しているときにフリーズします。以下は私のコードです:

  1. をクリックするbtnRunと、関数を呼び出しましたMainLoop()

    ActionListener btnRun_Click = new ActionListener() {
    
        @Override
        public void actionPerformed(ActionEvent e) {
            MainLoop();
        }
    };
    
  2. の実装MainLoop()

    void MainLoop()
    {
        Hopper = new CHopper(this);
        System.out.println(Hopper);
        btnRun.setEnabled(false);
        textBox1.setText("");
        Hopper.getM_cmd().ComPort = helpers.Global.ComPort;
        Hopper.getM_cmd().SSPAddress = helpers.Global.SSPAddress;
        Hopper.getM_cmd().Timeout = 2000;
        Hopper.getM_cmd().RetryLevel = 3;
    
    
        System.out.println("In MainLoop: " + Hopper);
    
        // First connect to the validator
        if (ConnectToValidator(10, 3))
        {
            btnHalt.setEnabled(true);
            Running = true;
    
            textBox1.append("\r\nPoll Loop\r\n"
                    + "*********************************\r\n");
        }
    
        // This loop won't run until the validator is connected
        while (Running)
        {
            // poll the validator
            if (!Hopper.DoPoll(textBox1))
            {
                // If the poll fails, try to reconnect
                textBox1.append("Attempting to reconnect...\r\n");
                if (!ConnectToValidator(10, 3))
                {
                    // If it fails after 5 attempts, exit the loop
                    Running = false;
                }
            }
            // tick the timer
                    // timer1.start();
            // update form
            UpdateUI();
            // setup dynamic elements of win form once
            if (!bFormSetup)
            {
                SetupFormLayout();
                bFormSetup = true;
            }
    
        }
    
        //close com port
        Hopper.getM_eSSP().CloseComPort();
    
        btnRun.setEnabled(true);
        btnHalt.setEnabled(false);
    }
    
  3. MainLoop()関数では、whileループは、Runningがtrueになるまで継続して実行されます。問題は、whileループを停止する場合、Runningをfalseに設定する必要があることです。これは、別のボタンで実行されますbtnHalt

    ActionListener btnHalt_Click = new ActionListener() {
    
        @Override
        public void actionPerformed(ActionEvent e) {
            textBox1.append("Poll loop stopped\r\n");
            System.out.println("Hoper Stopped");
            Running = false;
        }
    };
    

しかしbtnHalt、応答していません。フレーム全体がフリーズし、ログも表示されませんtextarea

4

1 に答える 1

2

Swing はシングル スレッド フレームワークです。つまり、再描画要求を含むすべてのイベントをすべてのコンポーネントにディスパッチする役割を担う単一のスレッドがあります。

このスレッドを停止/ブロックするアクションは、UI を「ハング」させます。

Swing の最初のルールは、ブロックするタスクや時間のかかるタスクをイベントディスパッチスレッドで実行しないことです。代わりに、バックグラウンド スレッドを使用する必要があります。

これは、Swing の 2 番目のルールに突き当たります。EDT 以外の UI コンポーネントを作成、変更、または操作しないでください。

これを修正する方法はいくつかあります。SwingUtilities.invokeLaterまたはを使用できますSwingWorker

SwingWorkerEDT への呼び出しを自動的に再同期するいくつかの使いやすいメソッドを提供するため、一般的に簡単です。

Swing での同時実行を読んでください。

更新しました

あなたが理解するように;)

MainLoopメソッドは EDT のコンテキスト内で実行されるべきではありません。これは非常に悪いことです。

また、EDT 以外のスレッドから UI コンポーネントとやり取りするべきではありません。

于 2013-03-21T05:47:19.260 に答える