【问题标题】:VB.NET Listen for TCP connections without wasting processor usageVB.NET 监听 TCP 连接而不浪费处理器使用
【发布时间】:2014-03-27 05:50:55
【问题描述】:

我正在使用 TCPListener 创建一个带有 VB.NET 的语音服务器。为了检查传入的连接,我在 Form Load 方法中创建了一个无限循环,只要连接可用,它就会接受它,然后创建一个新线程来处理通信。以下是代码:

Private WithEvents SR As New SoundRecorder
Private TCPListener As TcpListener

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    TCPListener = New TcpListener(Net.IPAddress.Parse(GetIPv4Address), 2021)
    TCPListener.Start()
    While 1
        If TCPListener.Pending = True Then
            Dim voiceCom As New BroadcastSound(TCPListener.AcceptSocket())
            Dim th As New Threading.Thread(AddressOf voiceCom.startCommunication)
            th.Start()
        End If
        Application.DoEvents()
    End While
End Sub

服务器完美运行并支持所有连接但问题是处理器使用率始终为 100%,因为无论是否连接任何客户端。有没有更好的方法来监听传入连接?

【问题讨论】:

    标签: .net vb.net tcplistener


    【解决方案1】:

    任何时候你发现自己在寻找Application.DoEvents,你应该尝试重新考虑 - 这通常是一种解决方法。至少这次你已经知道你的处境很糟糕:)

    如果您愿意同步执行所有操作,我会启动一个新线程,然后在其中调用TcpListener.AcceptTcpClient。 (如果您真的需要套接字,您可以调用TcpListener.AcceptSocket,但TcpClient 通常是一种更简单的方法。)该调用将阻塞,直到有一个客户端准备好,所以你不要需要循环检查Pending 属性。

    因此,您的 UI 线程将准备好接收 UI 事件,并且有一个线程等待入站请求。

    现在,您可以改用异步 API - 特别是如果您使用的是带有 Async 和 Await 的 VB11。你可以使用:

    Dim client As TcpClient = Await listener.AcceptTcpClientAsync();
    

    ... 在 UI 线程中。这不会阻塞 UI 线程,但会异步开始 接受传入连接。建立连接后,您的异步方法的其余部分将继续。你不需要额外的线程。您可以在 UI 线程上完成所有工作,使用异步来避免阻塞。这样可以更轻松地与 UI 交互,但需要一些时间来适应。

    如果您对异步和网络都不熟悉,我可能会开始使用同步版本...让您了解的内容会更少。然后,如果您以后喜欢冒险,可以将所有内容都转换为异步方法。

    【讨论】:

      【解决方案2】:

      我意识到这已经很老了,但在我搜索类似的东西时,这是第一个结果。

           Public Class main
      
              Private client As TcpClient
              Private listener As TcpListener
              Private WithEvents tcpBg As BackgroundWorker
      
              Private Sub main_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
                  tcpBg = New BackgroundWorker
                  'Requires a routine that cancels background worker.
                  tcpBg.WorkerSupportsCancellation = True
                  'ip is most likely from a Textbox.
                  Dim adr As Net.IPAddress = Net.IPAddress.Parse(ip)
                  listener = New TcpListener(adr, 60000)
      
                  tcpBg.RunWorkerAsync()
              End Sub     
      
              Private Sub tcpBg_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles tcpBg.DoWork
                  listener.Start()
                  While tcpBg.CancellationPending = False
                      client = listener.AcceptTcpClient
                      'Do something with your client.
                      client.Close()
                  End While
              End Sub
      
          End Class
      

      这就是我实现 TCPListener 的方式。我的 FX-8350 的使用率约为 0.1%。我无法确定我的 Athlon II X2 上的情况,但不会超过百分之几。 GUI 不会冻结,并且您不应该有任何实际的 CPU 使用率。

      当然,我的实际实现是在几个不同的类中。这是一个简单的基础示例。

      【讨论】:

        猜你喜欢
        • 2020-05-28
        • 2015-06-26
        • 1970-01-01
        • 2010-12-14
        • 2019-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多