-2

我编写了一个服务,它运行一个线程,每分钟设置一次设置。

该服务完成了它应该做的事情,但随后注意到它使 CPU 使用率变得非常高(在双核上约为 25%)。

通过反复试验,我发现以下对象导致了问题:

private AsyncPipes.NamedPipeStreamServer pipeServer = new NamedPipeStreamServer("NotifyToService");
private AsyncPipes.NamedPipeStreamClient pipeClient = new NamedPipeStreamClient("ServiceToNotify");

命名管道仅通过实例化就使用这么多 CPU 是否正常?

4

3 回答 3

5

我可以复制你的结果(我的 8 核 CPU 上的 13% 除外)。我必须从本文末尾下载并构建 AsyncPipes。问题是代码每秒NamedPipeStreamClient抛出一次。System.TimeoutException

在一种糟糕的设计方式中,构造函数NamedPipeStreamClient调用了StartTryConnect()在设置一些类成员后调用的方法。

反过来,该方法启动一个调用该方法的后台线程TryConnect。它在这里进入一个紧密的循环:

while (!this._Stream.IsConnected)
{
    try
    {
        ((NamedPipeClientStream) this._Stream).Connect(0x3e8);
    }
    catch
    {
    }
}

在您的客户端尝试连接的服务器(“ServiceToNotify”)实际启动之前,情况将如此。但是,我看不到在任何地方启动了命名管道服务器(您有相反的“NotifyToService”)。

但是,一旦它确实连接到服务器,CPU 使用率将按预期下降。

于 2013-06-19T15:59:25.197 回答
1

这就是我最终用来避免这个问题的方法。这是此 MSDN 论坛主题中显示的解决方案的一个非常简化的版本:

https://social.msdn.microsoft.com/Forums/en-US/7bbf5a0b-3c22-4836-b271-999e514c321b/namedpipeclientstreamconnect-causes-cpu-hang-is-there-a-workaround

  [return: MarshalAs( UnmanagedType.Bool )]
  [DllImport( "kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true )]
  private static extern bool WaitNamedPipe( string name, int timeout );


  /// <summary>
  /// Method to test if Windows considers that a named pipe of a certain name exists or not.
  /// </summary>
  internal static bool DoesNamedPipeExist(string pipeFileName)
  {
     try
     {
        return WaitNamedPipe(@"\\.\pipe\" + pipeFileName, 0);
     }
     catch (Exception)
     {
        return false;
     }
  }

这是使用 NamedPipeClientStream.Connect() 方法的地方的代码:

 // If necessary, wait for the server end to open the named pipe. Otherwise the following 
 //  NamedPipeClientStream.Connect() method can burn up 100% CPU time while waiting for 
 //  the connection. 
 while (true)
 {
    if (DoesNamedPipeExist(_pipeFileName))
       break;
    Thread.Sleep(1000);
 }

 // Connect to named pipe server - this is a blocking call, and in fact is a blocking 
 //  call that can use 100% CPU time while waiting for a connection
 _namedPipeClient.Connect();
于 2015-07-23T03:00:47.323 回答
-2

除非服务在某个时候休眠/等待,否则这是一种完全正常的行为。默认情况下,while true{}循环将使用其执行位置 100% 的处理能力。25% 听起来很像您计算机上可用的 4 个线程的 1/4。

您实际上想在编写代码时使用 100% 的 CPU,否则您为什么要为更快的计算机付费?...

于 2013-06-19T14:33:47.773 回答