问个关于Ping类的问题

yang1216 2013-06-24 09:54:44
先看我的代码

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啊,它直接报个错都行。
...全文
153 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
lgh365 2015-06-04
  • 打赏
  • 举报
回复
非常感谢,正是不太明白AutoResetEvent.WaitOne()的作用呢
  • 打赏
  • 举报
回复
这种问题你应该先查MSDN,然后再查一下那类的源码实现
人生导师 2013-06-24
  • 打赏
  • 举报
回复
因为你在自己机器上因为链接的都是本地的,所以程序运行没有延时,所以主程序运行结束后,后台线程也运行结束了,后台线程指的是运行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

111,119

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧