本帖最后由 pj220 于 2012-04-13 15:29:54 编辑

解决方案 »

  1.   

     try
               
              {
                  pingSender.PingCompleted += new PingCompletedEventHandler(pingSender.PingCompletedCallBack);
                  pingSender.SendAsync(args[0], timeout, buffer, null);
     
              }你把事件在外面加。
    在循环里面+= 造成最后事件数量是1000*1000个。
      

  2.   

    我能怎么说你呢?这哪里是内存泄漏啊,这其实是你并发开太多造成的。SendAsync是异步执行的方法,你一个100万次的循环里,一瞬间开了100万个并发操作,系统资源能足够吗?
      

  3.   


    我观察了进程管理器里面的线程数,线程数没有增加多少(没运行前1600多个线程,运行后 1900多个线程),也就增加了不到400个线程,系统完全能扛得住,问题是里面的那个句柄数增加太多了,没运行前句柄数10万多一点,运行后句柄数就一直增加,最后 90万都不止,明显 C#对ping 类里面的资源释放是有问题的
      

  4.   


    我写个循环只是为了让问题更容易出现,我曾经在循环里用sleep,或者写个界面弄个定时器,系统经过一定时间后,内存仍然是只增不减的,所以这个跟是否并发应该没有多大关系吧
      

  5.   

    我没用过Ping类,以前写过一个带ping的程序,是直接Process类调用系统的ping命令来实现的,只要重定向输出到自己的程序,接收回显内容判断是否连通。程序开着一整天不关,也没见内存半点有增长。
      

  6.   


    用你说的也是一种解决方案。
    不过如果不用ping 类的异步模式,我也没有内存增长的问题。而且用重定向还是没有直接这么用简单。
      

  7.   


    如果想讨论所谓“资源释放”有问题,你首先把Ping的Dispose源代码贴出来。它也不过做了7、7条代码而已嘛。既然你去分析它,就不要总是议论,应该围绕源代码来讨论。
      

  8.   

    基本上Ping总要等到超时的时候才知道返回对方不在线的结果,如果大量地去并发,你我们的普通的pc+windows系统是扛不住的。
      

  9.   


    我ping 的是局域网的网关,而且网络是通路,没有你说的对方不在线的问题。
    而且我今天再做,发现只要减少那个超时值为100或者更小,即使就是网络不通,内存根本就不是问题(内存已经增长极其缓慢了,抗住那个1000*1000循环绝对没问题)。 问题还是那个句柄数,句柄数的增加跟内存的增加成正比,也就是说我如果再增加一层1000的循环,内存是因为句柄数的增加而耗尽
      

  10.   


    我是怀疑ping 的 “资源释放”有问题,ping 的资源释放的代码在debug模式下跟不出来。
      

  11.   

    自己加个buffer是什么情况咧?
      

  12.   

    pingSender.SendAsync是异步调用托管线程池线程来执行的,当可用线程用完时,将排队。
    对于LZ千万级的实例,系统除了每个线程都要进入Ping等待返回,另一方面还需要维护这个队列,也许CPU占用并不会太高,但是系统能使用的TCP连接/半连接数是有限的,远远小于并发线程数自己想想吧
      

  13.   


    因为,嘴巴,食道,胃,大肠,不是一样的粗计算机里,程序,网卡,内存硬盘
    类似的问题还出现在,并发处理大量小文件的时候,如果不控制并发量,我的电脑上10分钟后会内存耗尽异常
    解决方法因为我用的是 并行 foreach 只需要设定最大并发量 maxdegreeofparallelism 就没有问题
      

  14.   

    上面那个回答错误,我删不掉了。我观察了进程管理器里面的线程数,线程数没有增加多少(没运行前1600多个线程,运行后 1900多个线程),也就增加了不到400个线程,系统完全能扛得住,问题是里面的那个句柄数增加太多了,没运行前句柄数10万多一点,运行后句柄数就一直增加,最后 90万都不止,明显 C#对ping 类里面的资源释放是有问题的你说对了,不要用using,
    (sender as IDisposable).Dispose();改成(sender as Ping).Dispose();,这是问题所在