vb.net - 自添加套接字通信以来,服务应用和表单应用的使用率都非常高 CPU

vb.net - service app & forms app both have very high CPU usage since adding socket comms

我有 2 个正在开发的应用程序 - 一个是 windows 服务,它执行后台任务和 api 调用等。 第二个是在用户上下文中运行的表单应用程序。表单应用程序的目的是在 windows 服务需要时向用户显示数据。

为了启用两个应用程序之间的通信,我使用了线程和套接字。 我以前没有这样做过,所以如果我犯了任何明显的错误,请放轻松。 两个应用程序中的代码几乎如下所示,除了每个应用程序的端口号不同...

 Imports System.Net.Sockets
 Imports System.Threading

Public Listener As New TcpListener(64420)
Public Client As New TcpClient
Public Message As String = ""

 Public Function StartListener()
    Try
        Dim ListenerThread As New Thread(New ThreadStart(AddressOf StartListener))
        ListenerThread.Start()
        Listener.Start()
        Timer1.Start()
    Catch ex As Exception

    End Try
End Function

Public Function MessageClient(ByVal Message As String)
    Try
        Client = New TcpClient("127.0.0.1", 64421)
        Dim Writer As New StreamWriter(Client.GetStream())
        Writer.Write(Message)
        Writer.Flush()
        Return "OK"
    Catch ex As Exception
        Return "Error"
    End Try
End Function

 Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    If Listener.Pending = True Then
        Message = ""
        Client = Listener.AcceptTcpClient()

        Dim Reader As New StreamReader(Client.GetStream())
        While Reader.Peek > -1
            Message = Message + Convert.ToChar(Reader.Read()).ToString
        End While
        ResponseCalc(Message)
        End If
    End Sub

两个应用程序之间的通信完美无缺,在这两种情况下,'message' 都传递给 ResponseCalc 函数,该函数确定两端需要做什么。

问题是,自从将其放入后,我的两个应用程序都使用了大量的 CPU。 以至于我不断地以 100% CPU 最大化我的机器。

有没有一种方法可以在不使用相应的疯狂 CPU 用法的情况下实现相同的结果?

否则,您还可以如何启用像这样的应用程序之间的通信?

最初我想 writing/reading 文件进出磁盘,但不想这样做,因为它感觉草率和业余。

如有任何帮助,我们将不胜感激!

问题出在您的 StartListener 函数上,它作为 externally-called 函数执行双重任务以启动侦听器线程,并作为该线程的启动函数。这正在创建一个无限递归。执行顺序如下所示:

  1. 从其他代码调用 StartListener
  2. StartListener 创建一个新线程,以 StartListener 作为启动例程。
  3. StartListener 启动新线程。
  4. 新线程启动 运行 并运行 StartListener
  5. 循环回到 (2)

要解决这个问题,启动例程应该不是 StartListener。我不确定除了托管套接字处理的某些方面之外,您是否真的需要线程做任何事情;如果它只需要存在,那么启动例程可以像空白一样简单Sub。否则,您可以内联编写它,或者可以将 AddressOf 与 separately-written 例程一起使用。

或者,在替代方案中,您可能根本不需要编写自己的线程,正如您的评论所暗示的那样。