读书人

问个关于Ping类的有关问题

发布时间: 2013-07-01 12:33:04 作者: rapoo

问个关于Ping类的问题
先看我的代码


private void commTest()
{
using (System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping())
{
ping.PingCompleted += ping_PingCompleted;
ping.SendAsync(_ip, null);
}
}
private void ping_PingCompleted(object sender, System.Net.NetworkInformation.PingCompletedEventArgs e)
{
if (e.Cancelled)
{
_isConnected = false;
labelStatus.Text = "连接测试被取消";
return;
}
if (e.Error != null)
{
labelStatus.Text = e.Error.Message;
_isConnected = false;
return;
}
if (e.Reply.Status == System.Net.NetworkInformation.IPStatus.Success)
{
labelStatus.Text = "已连接";
_isConnected = true;
return;
}
else
{
labelStatus.Text = "连接错误";
_isConnected = false;
return;
}
}


这样写的话,在我自己的机器上试了很多次一点问题没有,但是用到客户的机器上ping另外一个机器就会直接进入e.cancelled分支。
请问这是为什么?


后来我在ping.SendAsync(_ip, null); 后面加了一个System.Threading.Thread.Sleep(2000);就没事了。


我觉得就算是超时报警也不应该是cancel啊,它直接报个错都行。 ping类
[解决办法]
这种问题你应该先查MSDN,然后再查一下那类的源码实现
[解决办法]
因为你在自己机器上因为链接的都是本地的,所以程序运行没有延时,所以主程序运行结束后,后台线程也运行结束了,后台线程指的是运行ping_PingCompleted这个方法的线程,所以不会出错,然而你用另一个客户端的时候,因为异步线程不会阻塞主线程的运行,所以在ping_PingCompleted这个方法运行结束之前,主线程已经退出了,导致后台线程也退出,所以会进入Cancel分支的结果,然而你使用Thread.Sleep()操作,就是相当于阻塞了主线程的执行,但是这个过程后台线程(执行ping_PingCompleted这个方法的线程)还在执行,当阻塞时间到的时候,也就完成了ping_PingCompleted这个方法的执行了,所以才不会有问题的,其实你在MSDN Ping的异步使用中也可以找到答案的,你必须在主线程调用AutoResetEvent.WaitOne()来确保请求得到一个回复了。具体你可以参考下面的MSDNPing的使用:
http://msdn.microsoft.com/zh-cn/library/system.net.networkinformation.ping.aspx
同时这个例子的疑惑也说明你对多线程的不理解,更多多线程内容可以参考我的博客:
http://blog.csdn.net/lizhi3186575/article/details/8991281

读书人网 >C#

热点推荐