我有一个.net core 3.1应用程序,在Raspbian(Rasp Pi 3)上运行时占用了15-20%的CPU。当它在我的Windows PC上的Visual Studio中运行时,CPU图形显示0-1%
应用程序本身非常简单,它是一个C#控制台应用程序,具有从NuGet安装的System.IO.Ports和RabbitMQ。
Main()首先设置串行端口,并将mySerialFunc()分配给DataReceived事件。它还设置RabbitMQ,同样将myRabbitMQ()分配给消费者。接收到的事件。之后,main()进入while循环
static Main(string[] args)
{
// setup code and events here
// ……
while (runFlag)
{
}
}
像在Windows上一样,一切都很好,但是在Raspbian上,该应用将占用100%的CPU。哎呀…
所以我更改了应用程序并添加到System.Threading和System.Threading.Tasks中
所以我的while循环现在看起来像这样
Static async Task Main(string[] args)
{
// setup code and events here
// ……
while (runFlag)
{
await Task.Delay(1000);
}
}
这已将CPU降低到15-20%
很明显,CPU过多是由于连续运行一段时间导致的,因此,执行此操作的最佳方法是什么?
我基本上有两个功能,当串行端口发生故障或收到RabitMQ消息时,这些功能就会运行。当没有事件发生时,我只需要程序连续运行,直到将runFlag设置为false。
但是同时,它毕竟要在Rasp Pi上运行,所以不会占用太多CPU。
有什么想法吗?
非常感谢您对这个问题的评论。
此后,通过按照以下代码更改连续循环,我设法使我的应用程序在0.3-1%的CPU上运行。
using System;
using System.Threading;
namespace daemonTest_withThreadSleep
{
class Program
{
// Define a daemonRunFlag for continous running
static bool daemonRunFlag = true;
static readonly CancellationTokenSource tokenSource = new CancellationTokenSource();
static void Main(string[] args)
{
// Add event to handle process exits, such as HUP signals.
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
// Add the setup code here
// Add the event functions here
// Start the Daemon Running
Console.WriteLine("Starting Daemon");
while ((daemonRunFlag) && (!tokenSource.Token.IsCancellationRequested))
{
// This generates 100% CPU
System.Threading.Thread.Sleep(1000);
}
Console.WriteLine("Ending Daemon");
}
private static void CurrentDomain_ProcessExit(object sender, EventArgs e)
{
// Function is called because of an HUP signal.
// Set the haLogHandle daemonRunFlag to false.
daemonRunFlag = false;
// cancel the received token.
tokenSource.Cancel();
}
}
}
上面的代码还包括处理在Raspbian上运行的HUP信号。
[我注意到为什么System.Threading.Thread.Sleep(1000)
产生的CPU使用率比await Task.Delay(1000)
低
有什么想法吗?
while循环有什么作用?只需保持应用程序处于活动状态,以便可以控制事件?
如果是这样,您可以永远wait
。
static void Main(string[] args)
{
// setup code and events here
// ……
Task.Delay(-1).Wait();
}
我记得这样的事情可以使控制台应用程序保持运行状态
参考SerialPort Documentation on MSDN:
public void Read()
{
while (_continue)
{
try
{
string message = _serialPort.ReadLine();
Console.WriteLine(message);
}
catch (TimeoutException) { }
}
}
然后输入Main()
Thread readThread = new Thread(Read);
readThread.Start();