使用无限while循环处理客户机/服务器数据的最佳实践

本文关键字:数据 服务器 最佳 客户机 无限 while 循环 处理 | 更新日期: 2023-09-27 17:49:26

我正在开发一个客户端-服务器应用程序。我有一个无限while循环来检查客户端(或服务器)是否发送了数据。

while (true)
{
    // do things
}

但是这个的最佳实践是什么?使用上面的代码,当服务器接受客户机时,系统的CPU会跳转到100%。

如果我把Threading.Thread.Sleep(500)放在循环的末尾,CPU使用率会更好,但我想知道这是否是最好的方法,或者是否应该有所不同。

(我知道我能够异步获取数据——但我的问题不是这个,而是关于while循环的最佳实践,以便应用程序不会完全消耗CPU)

使用无限while循环处理客户机/服务器数据的最佳实践

我想知道这是否是最好的方法

没有逃逸机制的无限循环(break, yield return),(几乎)从来都不是一个好主意。

或者它应该是不同的

是的。

你正在做一个"忙等待"循环,等待客户端发送数据。所以你的循环应该是I/O限制的,而不是重复轮询的CPU限制。这一点在评论中已经提到过好几次了。

但是为了便于讨论,我们假设

  • 你的代码实际上是CPU限制的,
  • 定期需要"轮询"一些条件才能做某事,
  • 你不能使用标准的同步或信号原语(如阻塞队列、事件、信号量等)"等待"或"等待"该条件。

那么,任何解决方案至少有两部分需要考虑:

  1. 循环的停止条件。
  2. 只在实际需要的时候占用CPU和线程。
<

停止条件/strong>

这样做的一种方法是使用连接到CancellationTokenSourceCancellationToken来允许干净的停止方式。

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组件吗?这对你的情况很有用。