【问题标题】:Check for response every 100ms每 100 毫秒检查一次响应
【发布时间】:2014-02-09 00:51:05
【问题描述】:

我创建了这个 TCP 客户端,它正在工作,但是当它检查传入流时,它会暂停应用程序...(源代码 - https://app.box.com/s/7ly47ukztlo5eta3wqbk) 这是那部分:

        void check()
        {
            if (tcpclnt.Connected == true)
            {
                NetworkStream stm2 = tcpclnt.GetStream();
                if (stm2.CanRead)
                {
                    // Reads NetworkStream into a byte buffer. 
                    byte[] bytes = new byte[tcpclnt.ReceiveBufferSize];

                    // Read can return anything from 0 to numBytesToRead.  
                    // This method blocks until at least one byte is read.
                    stm2.Read(bytes, 0, (int)tcpclnt.ReceiveBufferSize);

                    // Returns the data received from the host to the console. 
                    string returndata = Encoding.UTF8.GetString(bytes);

                    log("SERVER: " + Environment.NewLine + returndata + Environment.NewLine);
                }
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            check();
        }

【问题讨论】:

  • 这方面的术语是“阻塞”与“非阻塞”套接字; “阻塞”套接字暂停直到数据可用,如果当前没有可用字节,“非阻塞”套接字将返回 0。您可以在 UI 线程上执行此操作,但您需要使用“非阻塞”套接字。
  • Read() 调用将阻塞,直到接收到数据。阻塞你的 UI 线程并让它变得紧张。这就是为什么有一个 NetworkStream.BeginRead() 方法,它不会阻塞。并且不需要计时器。查看 MSDN 文章以获得正确的代码。
  • 您忽略了来自stm2.Read 的返回值。那是一个错误。我很困惑,因为在您的评论中您甚至提到了这种可能性。

标签: c# .net tcp response tcpclient


【解决方案1】:

您的方法check()“暂停”应用程序,因为它的作业当前在 UI 线程中执行。

如果您不希望您的方法冻结 UI,您应该将方法的执行安排在与您的 UI 线程不同的后台线程中。

您可以使用BackgroundWorker 线程来做到这一点。正如@qujck 所建议的,一个例子是here

【讨论】: