我有一个网络项目,里面没有计时器。只是一个连接到服务器并侦听从网络接收任何数据的tcpclient。
TcpClient _TcpClient = new TcpClient(_IpAddress, _Port);
_ConnectThread = new Thread(new ThreadStart(ConnectToServer));
_ConnectThread.IsBackground = true;
_ConnectThread.Start();
private void ConnectToServer()
{
try
{
NetworkStream _NetworkStream = _TcpClient.GetStream();
byte[] _RecievedPack = new byte[1024 * 1000];
string _Message = string.Empty;
int _BytesRead;
int _Length;
while (_Flage)
{
_BytesRead = _NetworkStream.Read(_RecievedPack, 0, _RecievedPack.Length);
_Length = BitConverter.ToInt32(_RecievedPack, 0);
_Message = UTF8Encoding.UTF8.GetString(_RecievedPack, 4, _Length);
if (_BytesRead != 0)
{
//call a function to manage the data
_NetworkStream.Flush();
}
}
}
catch (Exception exp)
{
// call a function to alarm that connection is false
}
}
但是一段时间后我的应用程序的CPU使用率上升(90%,85%,...)。 即使没有数据接收。
任何人都可以给我一些关于cpu使用的提示。我完全是空白。我不知道我应该检查项目的哪个部分!
答案 0 :(得分:2)
任何人都可以给我一些关于cpu使用的提示
你应该考虑检查应用程序中的循环,比如while
循环,如果你花了这么多时间等待某些条件变为真,那么它将需要很多CPU时间。例如
while (true)
{}
或
while (_Flag)
{
//do something
}
如果while内部执行的代码是同步的,那么该线程将以大部分CPU周期结束。为了解决这个问题,你可以在不同的线程中执行while内的代码,因此它将是异步的,然后使用ManualResetEvent
或AutoResetEvent
报告执行操作的时间,另外要提到的是考虑使用System.Threading.Thread.Sleep
方法来使线程进入睡眠状态并给cpu时间执行其他线程,例如:
while(_Flag)
{
//do something
Thread.Sleep(100);//Blocks the current thread for 100 milliseconds
}
答案 1 :(得分:1)
你的代码有几个问题......最重要的是恕我直言:
BeginRead
等),而不是阻塞方法,不要创建自己的线程。线程“昂贵>”资源 - 并且在线程中使用阻塞调用因此浪费资源。使用异步调用可让操作系统在发生事件(例如,接收到的数据)时回调您,因此不需要单独的线程(回调使用池化线程运行)。Read
可能只返回几个字节,但不必填充_ReceivedPack
缓冲区。从理论上讲,它可能只收到一个或两个字节 - 甚至不足以拨打ToInt32
!答案 2 :(得分:1)
CPU使用率激增,因为如果没有从网络接收任何内容,你有一个while循环,它什么也不做。如果没有收到数据,则在它的末尾添加Thread.Sleep(),并且您的CPU使用率将是正常的。
接受Lucero给你的建议。
答案 3 :(得分:1)
我怀疑当while
循环仍在运行时,连接的另一端已关闭,在这种情况下,您将重复读取网络流中的零字节(标记连接已关闭;请参阅{{3} })。
由于NetworkStream.Read
将立即返回(根据MSDN),您将陷入紧张的while循环,这将消耗大量的处理器时间。尝试在循环中添加Thread.Sleep()或检测“零读取”。理想情况下,您应该通过终止连接的结束来处理零字节的读取。
while (_Flage)
{
_BytesRead = _NetworkStream.Read(_RecievedPack, 0, _RecievedPack.Length);
_Length = BitConverter.ToInt32(_RecievedPack, 0);
_Message = UTF8Encoding.UTF8.GetString(_RecievedPack, 4, _Length);
if (_BytesRead != 0)
{
//call a function to manage the data
_NetworkStream.Flush();
}
}
答案 4 :(得分:0)
您是否已附加调试器并逐步执行代码以查看其是否按预期方式运行?
或者,如果您有可用的分析工具(例如ANTs),那么这将帮助您了解应用程序的时间花在哪里。