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

标签 c# while-loop

<分区>

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

while (true)
{
    // do things
}

但是最好的做法是什么?通过上面的代码,当服务端接受一个客户端时,系统的CPU会跳到100%。

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

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

最佳答案

I wonder whether this is the best way

没有。

没有转义机制(breakyield return)的无限循环(几乎)永远不是一个好主意。

or that it should be different

是的。

您正在进行“忙等待”循环,等待客户端发送数据。所以你的循环应该是 I/O 绑定(bind)的,而不是通过重复轮询来绑定(bind) CPU 的。这一点已经在评论中多次提及。

但是为了论证我们假设

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

那么任何解决方案都至少需要处理两个部分:

  1. 循环的停止条件。
  2. 仅在实际需要时才消耗 CPU 并占用一个线程。

停止条件

执行此操作的一种方法是使用连接到 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 的定时器
  • 根据需要动态调整计时器间隔。

关于c# - 使用无限 while 循环处理客户端/服务器数据的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30291369/

相关文章:

c# - Linq2Twitter - 什么是 OAuthToken?

java - 如果输入非int值如何退出While循环?

java - while循环忽略or语句

c# - 在 NuGet 中添加同一包的 2 个不同版本

c# Form.Hide() 与 Form.Opacity = 0

c# - 为什么将值转换为 IEnumerable<T> 的行为会根据我初始化值的方式而有所不同?

php - 将从 mysql 检索的所有值乘以一个常量

python - While 循环的问题

Bash脚本,while循环中的多个条件

c# - 避免 if/else 的最佳实现