【问题标题】:C# TCP Client using high CPU when launched with Process.Start使用 Process.Start 启动时使用高 CPU 的 C# TCP 客户端
【发布时间】:2020-12-31 14:50:51
【问题描述】:

我有一个 ASP Net Core 3.1 Web 应用程序,它在启动时启动一个控制台应用程序...

Process p = new Process ();
p.StartInfo.FileName = Path.Combine ( env.ContentRootPath , "MyProcess" , "myprocess.exe" );
p.Start ();

启动的进程会像这样监听 TCP 连接:

while ( true )
{
     if ( theTcpListenerServer.Pending() )
     {
         Task.Run(() =>
         {
            using ( TcpClient client = theTcpListenerServer.AcceptTcpClient() )
            {
                try
                {
                    byte[] aByteArray = new byte[ client.SendBufferSize ];

                    theStream = client.GetStream()
                    int aRecv;

                    while ( true )
                    {
                        aRecv = theStream.Read(aByteArray , 0 , client.SendBufferSize);
                        aData = System.Text.Encoding.ASCII.GetString(aByteArray , 0 , aRecv);

                        if ( !string.IsNullOrEmpty(aData) )
                        {
                            RaisePackageReceivedEvent(aData);
                            break;
                        }
                    }
                }
                catch ( Exception e )
                {
                    //log some info
                }
            }
        });
    }
    Thread.Sleep(10);
}

如果我独立启动此进程,它几乎会在 0% 的 CPU 上运行,但从 Web 应用程序启动它会占用 30% 的 CPU。最初代码没有 Task.Run 位,我还添加了 Thread.Sleep(10)。当我调用 Process.Start 时,我也尝试重定向输出,但没有任何帮助。

【问题讨论】:

  • 我不是这方面的专家,但 while(true) 是 CPU 的敌人。
  • @MonkeyDLuffy 当我在其他答案中阅读时,这就是 Thread.Sleep(10) 应该提供帮助的地方。但这并不能解释从 exe 或使用 Process.Start() 启动它的区别,对吧?
  • 你在什么时候等待任务
  • @Charlieface 我没有,但实际上它永远不会达到那个点,因为当没有建立连接时会发生这种情况(即,Pending() 总是错误的)

标签: c# asp.net asp.net-core


【解决方案1】:

您可能想在生成任务之前调用theTcpListenerServer.AcceptTcpClient()。然后在任务中处理接收到的客户端。无需调用theTcpListenerServer.Pending(),这会浪费cpu 周期。 AcceptTcpClient 会做正确的事并在阻塞和等待连接时使用最少的 CPU。

无论哪种方式,这似乎都是您可以直接在您的网络应用程序中生成的任务。无需其他流程。

【讨论】:

  • 感谢您的回复!我实际上添加了待处理,但它是像你之前说的那样写的(并且没有工作)。但是,问题终于出在了另一个地方(我稍后会添加一个答案)。我必须在另一个进程中执行此操作,因为这使用了一些我无法控制的 Windows 本机代码,并且我必须维护通用应用程序跨平台。
【解决方案2】:

在拉了我很多头发之后,错误出现在代码的另一部分(在网络应用程序中)。我正在执行以下操作:

using (TcpClient client = new TcpClient("localhost", port)){
    JObject jsonObj = myObj.ToJSON(); // can return null if error
    if(jsonObj == null) return false;

    // rest of operations
}

由于某种原因,打开 TCP 客户端并且不执行任何操作失败(可能它在第二个 while(true) 内挂起,但我不确定)。

移动代码后,它看起来像这样......

JObject jsonObj = myObj.ToJSON(); // can return null if error
if(jsonObj == null) return false;

using (TcpClient client = new TcpClient("localhost", port)){
    // rest of operations
}

它与应该工作的对象完美配合,并且在 JSON 为空时不会打开空 TCP 客户端。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-23
    • 1970-01-01
    相关资源
    最近更新 更多