c# - 什么是快速测试多个盒子 ping 的最佳方法

标签 c# monitoring ping

我有一个应用程序,我可以监视和控制一堆计算机(可能是 3 到 35 台左右,可能是本地计算机)。

我监控的其中一件事是正常运行时间/ping 状态。该应用程序的目的之一是重新启动盒子,有时它们会因其他原因而重新启动。

我希望能够快速获取可 ping/不可 ping 的更改。

我在一个线程上有一个自旋循环。

在我看来,阻止 ping 会阻止它更新一点,即使你并行运行它(防止一个盒子的 ping 阻塞另一个盒子)

(并行实现示例,注意以下只是我的脑洞,还没有实现,可能有错误)

var startTime = DateTime.Now;
var period = TimeSpan.FromSeconds();
Parallel.ForEach(boxes, (box) => 
{
    var now = DateTime.Now;
    var remainingTime = (now - startTime) - period;
    while(remainingTime > TimeSpan.Zero)
    {
        box.CanPing.TryUpdate();
    }
});

TryUpdate 就像

using(ping = new Ping())
{
    var reply = ping.Send (IP);
    bool upStatus = (reply.Status == IPStatus.Success);
    this.Value = upStatus;
}

或者,我尝试使用多个 SendAsync(一次多个异步 ping)通过在 SendAsync 的回调中双重检查锁定来尽快发现正常运行时间

if(upStatus != this.Value)
{
    lock(_lock)//is it safe to have a non static readonly lock object, all the examples seem to use a static object but that wouldn't scale to  locking in multiple instances of the containing class object
    {
        if(upStatus != this.Value)
        {
            ...
        }
    }
}

这是一个可怕的内存泄漏,但这可能是因为我太快进行了太多异步 ping 调用(每个调用都带有一个线程),而没有处理 ping。如果我一次将自己限制为每台计算机 3 个,或者在中间暂停更长的时间,然后 Dispose() the ping 你认为这是个好主意吗?

什么是更好的策略?还有其他想法吗?

最佳答案

这是多线程的一个特殊情况,您不需要线程来使程序更快,您需要使其响应更快。您的操作几乎不需要计算能力。因此,我不会害怕为每台受监控的计算机创建一个线程。无论如何,他们大部分时间都在做 sleep()。它们应该被创建一次,因为线程创建实际上是这里最昂贵的事情。

我会像这样创建对象层次结构:

  • GUIProxy - 将处理所有图形用户界面操作,例如更改计算机名称旁边的通知颜色
  • HostManager - 将注册新机器,移除旧机器,对Monitors
  • 执行计时检查
  • HostMonitor - 会定期按顺序发送 ping 以检查计算机。稍后会详细介绍它的行为

检查算法

在 LAN 中,大多数时间 ping 在发送后 1-2 毫秒内返回。在 Internet 上,时间可能会有所不同。 我会根据机器位置为每个 Monitor 分别设置两个 ping 时间阈值。当 LAN ping 大于 5ms 或 Internet ping > 200ms 时,一个是“警告”阈值(GUI 中的黄灯或某物)。第二个是“错误”阈值,LAN > 1s 和 Internet > 2s 或某物。 每个 Monitor 都会发送 ping,等待应答,并在收到应答后发送另一个 ping。它应该存储 lastPingSendTimelastPingReceiveTimecurrentPingSendTime。前者用于确定延迟,后者用于检查 HostManager 中的延迟。当然,Monitor 应该正确处理超时和其他系统/网络事件。

在同样在单线程上运行的 HostManager 中,我会检查每个 Monitor 上的 currentPingSendTime 并根据该监视器的阈值检查它。如果超过阈值,GUIProxy 将收到通知以在 GUI 中显示情况。

优点

  • 你自己控制线程
  • 你可以使用synchronous(simpler) ping method
  • Manager 不会挂起,因为它异步访问 Monitors
  • 您可以实现一个抽象的 Monitor 接口(interface),您可以使用它来监控其他事物,而不仅仅是计算机

缺点

  • 正确的Monitor线程实现可能并不简单

关于c# - 什么是快速测试多个盒子 ping 的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17378761/

相关文章:

c# - 在 C# 中拆分数组的最快(可移植)方法

c# - 在不使用错误处理的情况下监视 c# web 服务的状态

用于检查互联网连接不工作的 Linux bash 脚本

c# - 如何仅 Ping IPv4?

networking - 是否可以使用 ping 测量带宽?

c# - 以编程方式在 Web 浏览器中打开文本文件

c# - 如何使用 RestSharp 为不记名 token 实现自定义 IAuthenticationModule

c# - Entity Framework IQueryable 扩展方法不能用作子查询

java - 我们如何衡量私有(private)方法的执行时间呢?

iOS区域监控,监控20多个位置