我有一个应用程序,我可以监视和控制一堆计算机(可能是 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。它应该存储 lastPingSendTime
、lastPingReceiveTime
和 currentPingSendTime
。前者用于确定延迟,后者用于检查 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/