none
关于C#中Ping.SendAsync和异步的问题 RRS feed

  • 问题

  • 我写了一个测试一组ip地址ping值的程序,然后使用ping.sendaysnc方法,但是现在问题是如果其中有一条记录出现timeout的话,下面所有的都会出现timeout(比如说到第100条,ip地址没法ping通,那么之后的31条记录都会返回timeout的结果)。

    在MSDN查看实例中,里面有提到waiter,用来保证每次执行sendaysnc都能得到答复。但是我不理解的是什么原因造成的上述情况,再循环的时候每个ping操作不是都用使用的不同的new出来的实例么,为什么在timeout之前的记录都能答复成功?而如果其中有一个阻塞了剩下的都会返回Timeout,是什么原理。阻塞后程序内部究竟发生了什么?请教!谢谢

    //cdn1.txt中有131条ip记录
    //ip记录格式192.168.1.1 www.baidu.com
    private static void Main()
    {
                var sr = new StreamReader("cdn1.txt");
                while (true)
                {
                    string str = sr.ReadLine();
                    if (String.IsNullOrEmpty(str))
                        break;
                        PingFunc(str);
                }
                sr.Close();
                Console.ReadLine();
    }
    
    private static void PingFunc(string str)
    {
                testping = new Ping();
                string ip = str.Split(' ')[0];
                testping.PingCompleted += PingSuccess;
                testping.SendAsync(ip, 1000, str);
    }
    
    static void PingSuccess(object sender, PingCompletedEventArgs e)
    {
                lock (_lock)
                {
                            string temp = e.UserState + "请求结果:" + e.Reply.Status + "(编号" + i + "),耗时:" + e.Reply.RoundtripTime + "ms";
                            result.AppendLine(temp);
                            StreamWriter sw = new StreamWriter("result.txt", true);
                            sw.WriteLine(temp);
                            sw.Close();
                            Console.WriteLine(temp);
                }
    }


    我只愿面朝大海,春暖花开……

    2013年7月5日 5:35

答案

  • 因为你使用lock,这个导致了一个timeout(假设其中某个timeout了),那么其余的势必会timeout(因为一个延时,其余的多线程无法访问这个事件,因为你加了lock)。

    解决方案,移除lock:

    namespace Csharp
    {
        public class Test
        {
            static AutoResetEvent flag = new AutoResetEvent(false);
            static void Main(string[] args)
            {
     
                Ping p = new Ping();
                p.PingCompleted += p_PingCompleted;
                p.SendAsync("www.baidu.com"1000null);
                flag.WaitOne();
     
                //延时的
                p = new Ping();
                p.PingCompleted += p_PingCompleted;
                p.SendAsync("www.google.com"1000null);
                flag.WaitOne();
     
                p = new Ping();
                p.PingCompleted += p_PingCompleted;
                //正常的
                p.SendAsync("www.online.sh.cn"1000null);
                flag.WaitOne();
            }
     
            static void p_PingCompleted(object senderPingCompletedEventArgs e)
            {
                if (e.Reply != null)
                {
                    Console.WriteLine(e.Reply.Address + "\t状态:" + e.Reply.Status);
                    flag.Set();
                }
            }
        }
    }

    If you think one reply solves your problem, please mark it as An Answer, if you think someone's reply helps you, please mark it as a Proposed Answer

    Help by clicking:
    Click here to donate your rice to the poor
    Click to Donate
    Click to feed Dogs & Cats


    Found any spamming-senders? Please report at: Spam Report


    2013年7月5日 6:53
    版主