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你认为这是个好主意吗?
什么是更好的策略?还有其他想法吗?
这是多线程的一个特例,你不需要更快地使程序更快,你需要使它更具响应性.您的操作几乎没有计算能力.因此,我不会害怕为每台受监视的计算机创建一个单独的线程.sleep()无论如何,他们将会做大部分时间.它们应该被创建一次,因为创建线程实际上是最昂贵的东西.
我会像这样创建对象层次结构:
GUIProxy - 将处理所有gui操作,例如更改coputer名称旁边的通知颜色HostManager - 将注册新机器,删除旧机器,执行时间检查 MonitorsHostMonitor - 会定期,顺序发送ping检查计算机.稍后会有更多关于它的行为在LAN中,大多数时间ping在发送后1-2毫秒内返回.在互联网上,时间可能会有所不同.我将为每个阈值分别设置两个ping时间阈值Monitor,具体取决于机器位置.当LAN ping大于5ms或Internet ping> 200ms时,一个是"警告"阈值(GUI中的黄灯或sth).第二个是"错误"阈值,LAN> 1s,Internet> 2s或sth.每个人Monitor都会发送ping,等待答复,并在收到答案后发送另一个ping.它应该存储lastPingSendTime,lastPingReceiveTime和currentPingSendTime.前者用于确定延迟,后者用于检查延迟HostManager.当然Monitor应该正确处理超时和其他系统/网络事件.
在HostManager,也在单个线程上运行,我会检查currentPingSendTime每个监视器上的内容并根据监视器的阈值进行检查.如果超过阈值,GUIProxy将通知GUI以显示GUI中的情况.
好处
Manager 不会挂起,因为它异步访问监视器缺点
Monitor线程实现可能并不简单| 归档时间: |
|
| 查看次数: |
1007 次 |
| 最近记录: |