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

Rom*_*her 5 c# monitoring ping

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

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

我希望能够快速获取pingable/non-pingable更改.

我在一个线程上有一个旋转循环.

在我看来,阻止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();
    }
});
Run Code Online (Sandbox Code Playgroud)

其中TryUpdate就是这样的

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

或者,我尝试使用多个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)
        {
            ...
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个可怕的内存泄漏,但这可能是因为我做太多异步ping调用(每个都带有一个线程)太快,而不是处理ping.如果我一次限制自己每台计算机3个,或者在中间放置一个更长的停顿,并且Dispose()ping你认为这是个好主意吗?

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

Dar*_*usz 8

这是多线程的一个特例,你不需要更快地使程序更快,你需要使它更具响应性.您的操作几乎没有计算能力.因此,我不会害怕为每台受监视的计算机创建一个单独的线程.sleep()无论如何,他们将会做大部分时间.它们应该被创建一次,因为创建线程实际上是最昂贵的东西.

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

  • GUIProxy - 将处理所有gui操作,例如更改coputer名称旁边的通知颜色
  • HostManager - 将注册新机器,删除旧机器,执行时间检查 Monitors
  • HostMonitor - 会定期,顺序发送ping检查计算机.稍后会有更多关于它的行为

检查算法

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

HostManager,也在单个线程上运行,我会检查currentPingSendTime每个监视器上的内容并根据监视器的阈值进行检查.如果超过阈值,GUIProxy将通知GUI以显示GUI中的情况.

好处

  • 你自己控制线程
  • 你可以使用同步(简单)ping方法
  • Manager 不会挂起,因为它异步访问监视器
  • 您可以实现一个抽象的Monitor接口,您可以使用它来监视其他内容,而不仅仅是计算机

缺点

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