簡體   English   中英

啟用的計時器不打勾

[英]Enabled timer does not tick

我正在用 c# 編寫一個簡單的 tcp 通信程序。 我想要的是通過在客戶端收到特定消息時啟用它來啟動計時器。 問題是,定時器在啟用時不會滴答作響。 我正在使用 System.Windows.Forms.Timer。

        void ReceiveData()
    {
        int recv;
        string stringData;
        while (true)
        {
            recv = client.Receive(data);
            stringData = Encoding.ASCII.GetString(data, 0, recv);
            if (stringData == "/starttimer" & !timer1.Enabled)
            {
                timer1.Enabled = true;
                break;
            }

            
        }
    }

    Stopwatch player1timer = new Stopwatch();
    void timer1_Tick(object sender, EventArgs e)
    {
        if (player1timer.IsRunning)
        {
            pl1label.Text = Convert.ToDouble(2) - Convert.ToDouble(player1timer.Elapsed.Minutes.ToString("00")) + ":" +
          Convert.ToString(Convert.ToDouble(59) - Convert.ToDouble(player1timer.Elapsed.Seconds.ToString("00"))) + "." +
          Convert.ToString(Convert.ToDouble(999) - Convert.ToDouble(player1timer.Elapsed.Milliseconds.ToString("00")));
        }
        
    }

由於這是一個 UI 程序,您需要小心避免阻塞 UI 線程。

在您的示例中, Receive可能會阻塞 UI 線程,直到有一些數據。 如果計時器已經啟用,或者它沒有收到所需的消息,它將繼續這樣做。 這將阻止 UI 執行其他操作,例如更新圖形或處理鼠標和鍵盤事件。 永遠不要阻塞 UI 線程

為避免這種情況,您需要使用異步編程或后台線程。 由於后台線程需要對線程安全有相當好的理解,我建議使用異步方法。

我沒有任何完整的例子,如果這是家庭作業,這樣的例子可能會適得其反,但總體方法應該是:

  1. TcpListner創建 TcpClient
  2. TcpClient.GetStream()獲取 NetworkStream
  3. 將此流包裝在 streamReader 中,並使用ReadLineAsync()讀取行。 在創建閱讀器時使用您想要的任何文本編碼。
  4. 等待返回的任務以獲取實際的字符串。

您可以在異步方法內的無限循環中執行此操作。 不應該阻塞,因為await會讓 UI 線程在等待數據時做其他事情。 請記住將方法的內容包裝在 try/catch 中,否則異常可能會丟失。

這應該適用於演示概念的簡單應用程序,但對於實際使用,我強烈建議使用庫來處理通信。 這很可能會更容易使用。

請注意,一些返回任務的方法是謊言,並且是假裝異步的真正同步方法。 這顯然行不通,但從文檔中很難分辨,因此嘗試通常是最簡單的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM