【问题标题】:Does Thread.Sleep deactivates a TCPListener?Thread.Sleep 是否会停用 TCPListener?
【发布时间】:2012-05-14 20:45:45
【问题描述】:

我有一个这样的线程:

        Public Sub StartWork()
        Try
            myTCPListener.Start()
            While StopRequest = False
                Dim requestspending As Boolean = m_TCPListener.Pending()
                If myTCPListener.Pending = False Then
                    Threading.Thread.Sleep(100)
                Else
                   DoSomething()
                End If

            End While
        Catch ex As Exception
            Throw ex
        End Try
    End Sub

现在我的问题是:当这里什么都没有发生时,我通过 Thread.Sleep 将线程发送到睡眠模式。这是否会以某种方式影响 TCPListener 的工作以及线程处于睡眠模式时传入的连接会发生什么?

【问题讨论】:

  • 是的。代码很奇怪,只有在有人尝试连接时才做 DoSomething。所以不要打扰,只需调用 AcceptSocket 代替,这样您就不必睡觉以避免烧核。
  • 问题是,当我在没有 thread.sleep 的情况下运行它时,程序占用了我的 cpu 的 33%(amd x6 现象),而使用 thread.sleep 它只占用了 17%。所以当线程休眠时,连接仍然可以挂起,但不能被接受,我做对了吗?
  • 很不清楚如何使用 Thread.Sleep(100) 调用来烧掉 17% 的内核。无论如何,您绝对应该更喜欢从 AcceptSocket 获得的 0%。

标签: .net vb.net multithreading tcp tcplistener


【解决方案1】:

当您的线程处于睡眠状态时,它不能做任何事情。特别是它将无法接受连接。因此,连接到您的客户端将不得不等待 100 毫秒,直到连接建立(当您调用 Accept 和 Accept 返回时连接建立)。

【讨论】:

    【解决方案2】:

    侦听 TCP 连接并为其提供服务是一种标准设计模式。有一种比代码中更好的方法。使用TcpListener.AcceptTcpClient(),它会阻塞直到有连接请求,当发生这种情况时,它会返回TcpClient,您可以使用它为客户端提供服务。即使AcceptTcpClinet() 是一个阻塞调用(在有请求之前不会返回),它也不会使用 CPU 时间。由于这正是您在代码中所做的(在有请求之前什么都不做),它会做您想要的工作。

    通常您应该避免使用Thread.Sleep(),因为这不是放弃 CPU 时间的最佳方式。你应该使用专门的监听方法,比如AcceptTcpClinet()、定时器、异步调用、WaitHandleThread.Join()等等。这样做更难,有时也不值得,但这应该是你的目标。

    【讨论】:

      【解决方案3】:
      Dim connection As Socket
      Dim reader As BinaryReader
      Dim writer As BinaryWriter
      Dim socketStream As NetworkStream
      Dim listener As TcpListener
      
      Dim ip As IPAddress = IPAddress.Parse(ipstring)
      listener = New TcpListener(ip, portnumber)
      listener.Start()
      
      connection = listener.AcceptSocket()
      socketStream = New NetworkStream(connection)
      writer = New BinaryWriter(socketStream)
      reader = New BinaryReader(socketStream)
      

      这是处理传入连接的有效方法:-),您不必让任何东西进入睡眠状态。如果性能是一个问题,请降低线程的优先级。例如:

      serverthread.Priority = ThreadPriority.BelowNormal
      

      【讨论】:

        猜你喜欢
        • 2010-11-13
        • 2016-12-18
        • 2014-03-23
        • 2016-02-03
        • 2010-10-02
        • 1970-01-01
        • 1970-01-01
        • 2010-09-26
        • 2015-07-08
        相关资源
        最近更新 更多