简体   繁体   English

C# TCP 客户端在使用 Process.Start 启动时使用高 CPU

[英]C# TCP Client using high CPU when launched with Process.Start

I have an ASP Net Core 3.1 web app which launches a console app on startup...我有一个 ASP Net Core 3.1 web 应用程序,它在启动时启动一个控制台应用程序......

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

The process launched listens for TCP connections like this:启动的进程监听 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);
}

This process runs on pretty much 0% CPU if I launch it standalone, but launching it from the web app makes it use like 30% CPU.如果我独立启动此进程,它几乎在 0% 的 CPU 上运行,但从 web 应用程序启动它使其使用 30% 的 CPU。 Originally the code did not have the Task.Run bit and I also added the Thread.Sleep(10).最初代码没有 Task.Run 位,我还添加了 Thread.Sleep(10)。 I tried redirecting output as well when I call Process.Start, but nothing helped.当我调用 Process.Start 时,我也尝试重定向 output,但没有任何帮助。

You would want to call theTcpListenerServer.AcceptTcpClient() before you spawn off the task.在生成任务之前,您可能需要调用theTcpListenerServer.AcceptTcpClient() Then process the received client in the task.然后在任务中处理接收到的客户端。 No need to call theTcpListenerServer.Pending() , that will waste cpu cycles.无需调用theTcpListenerServer.Pending() ,这将浪费 cpu 周期。 AcceptTcpClient will do the right thing and use minimal CPU while blocking and waiting for a connection. AcceptTcpClient在阻塞和等待连接时会做正确的事情并使用最少的 CPU。

Either way, this seems like something you could just spawn in a task directly in your web app.无论哪种方式,这似乎都是您可以直接在 web 应用程序中生成的任务。 No need for another process.不需要另一个过程。

After pulling my hair a lot, the error was in another part of the code (in the web app).在拉了很多头发之后,错误出现在代码的另一部分(在 web 应用程序中)。 I was doing the following:我正在做以下事情:

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

    // rest of operations
}

For some reason, opening the TCP client and not doing anything was failing (probably it hanged inside the second while(true), but I'm not sure).出于某种原因,打开 TCP 客户端并且不执行任何操作失败(可能它挂在第二个 while(true)内,但我不确定)。

After moving the code so it looks like this...移动代码后,它看起来像这样......

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

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

It works perfectly with the objects that are supposed to work, and does not open empty TCP Clients when the JSONs are null.它与应该工作的对象完美配合,并且当 JSON 为 null 时,不会打开空的 TCP 客户端。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM