使用无限while循环处理客户机/服务器数据的最佳实践
本文关键字:数据 服务器 最佳 客户机 无限 while 循环 处理 | 更新日期: 2023-09-27 17:49:26
我正在开发一个客户端-服务器应用程序。我有一个无限while循环来检查客户端(或服务器)是否发送了数据。
while (true)
{
// do things
}
但是这个的最佳实践是什么?使用上面的代码,当服务器接受客户机时,系统的CPU会跳转到100%。
如果我把Threading.Thread.Sleep(500)
放在循环的末尾,CPU使用率会更好,但我想知道这是否是最好的方法,或者是否应该有所不同。
(我知道我能够异步获取数据——但我的问题不是这个,而是关于while循环的最佳实践,以便应用程序不会完全消耗CPU)
号我想知道这是否是最好的方法
没有逃逸机制的无限循环(break
, yield return
),(几乎)从来都不是一个好主意。
或者它应该是不同的
是的。
你正在做一个"忙等待"循环,等待客户端发送数据。所以你的循环应该是I/O限制的,而不是重复轮询的CPU限制。这一点在评论中已经提到过好几次了。
但是为了便于讨论,我们假设
- 你的代码实际上是CPU限制的,
- 你定期需要"轮询"一些条件才能做某事,
- 你不能使用标准的同步或信号原语(如阻塞队列、事件、信号量等)"等待"或"等待"该条件。
那么,任何解决方案至少有两部分需要考虑:
- 循环的停止条件。
- 只在实际需要的时候占用CPU和线程。
停止条件/strong>
这样做的一种方法是使用连接到CancellationTokenSource
的CancellationToken
来允许干净的停止方式。
while (!cancelToken.IsCancellationRequested)
{
// Do stuff
// Note: this still does not solve the issue of eating CPU resources.
// If you were not polling periodically but waiting for a condition,
// you could now do:
try
{
var someResult = await MyCancelableAsyncOperation(..., cancelToken);
// do stuff with this result.
}
catch (OperationCanceledException)
{
break; // done
}
}
定期轮询
如果你需要定期做一些事情,使用一个可取消的计时器。示例如下:https://stackoverflow.com/a/30225642/2573395
注意,这个例子说明了基本思想。可以修改为:
- 使用与
System.Timers.Timer
不同的定时器 - 根据需要动态调整定时器间隔
您听说过BackgroundWorker
组件吗?这对你的情况很有用。