C#查找大型子网中的所有可用主机 [英] C# Find all available hosts in large subnet

查看:84
本文介绍了C#查找大型子网中的所有可用主机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我有65000多个可能的主机,我只想对它们全部执行ping操作并找出活动主机.该代码有效,但是还有其他问题.
当我查看自己的过程信息时,我看到我的活动线程随时间增加.我还注意到,使用此代码后,有很多线程保持打开状态.

I have 65000+ possible hosts, i just want to ping them all and get out the active hosts. This code works, but it has other issues.
When i watch my process informations i see my active threads increasing by time. I also notice that there are a lot of threads stay open after i used this code.

运行此代码还会占用大量内存,这就是为什么我同时使用最多5000台主机的原因.而且我多次执行此检测时,也发现有泄漏的地方.

Running this code also uses a lot of memory, that's why i used the maximum of 5000hosts at the same time. And i see there is also somewhere a leak when i do this detection multiple times.

这部分代码的CPU使用率也很高.

CPU Usage is also high for this part of code.

请注意,这是我在此代码中对每个主机进行的单个调用,我执行了65000个这些调用.在测试此代码时执行此操作,如果仅使用1个主机,则不会看到它的影响.

Notice this is the single call for each host i do in this code, i do 65000 of these calls. Do this when you test this code, if you only use 1 host you won't see the impact of it.

        private static int _ping_count = 0;
        private static object _lock_ping_count = new object();
        //private const string ALPHA_NUMERIC_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        private static byte[] PING_BUFFER = Encoding.ASCII.GetBytes("01234567890123456789012345678901");
        //private static Random _random = new Random();

        public void Detect()
        {
            if (_disposed) return;

            try
            {
                while (_ping_count >= 5000) //Let only 5000 hosts ping at the same time.
                {
                    if (_disposed) return;
                    Thread.Sleep(100);
                }

                lock (_lock_ping_count) _ping_count++;
                Ping ping = new Ping();
                //byte[] data = Encoding.ASCII.GetBytes(new string(Enumerable.Repeat(ALPHA_NUMERIC_CHARACTERS, 32).Select(s => s[_random.Next(s.Length)]).ToArray()));
                ping.PingCompleted += PingCompleted;
                ping.SendPingAsync(BaseAddress, 100, PING_BUFFER);
            }
            catch (Exception ex)
            {
                LogFile.Instance().Append(ex);
                LogFile.Instance().Append(Convert.ToString(BaseAddress));
                ThreadPool.QueueUserWorkItem((_) => OnDetectionCompleted());
            }
        }
        private void PingCompleted(object sender, PingCompletedEventArgs e)
        {
            if (_disposed) return;

            Ping ping = sender as Ping;

            if (ping != null)
            {
                ping.PingCompleted -= PingCompleted;
                ping.Dispose();
                ping = null;
            }

            if (e.Reply != null && e.Reply.Status == IPStatus.Success)
            {
                Console.WriteLine("{0}: {1}", BaseAddress, _ping_retries);
                Protocol = PROTOCOL.ICMP;
                //DetectProtocol();
                ThreadPool.QueueUserWorkItem((_) => OnDetectionCompleted());
            }
            else if (_ping_retries < PING_MAXIMUM_RETRIES)
            {
                _ping_retries++;
                ThreadPool.QueueUserWorkItem((_) => Detect());
            }
            else
            {
                ThreadPool.QueueUserWorkItem((_) => OnDetectionCompleted());
            }

            lock (_lock_ping_count) _ping_count--;
        }

推荐答案

您的资源正在增加的原因是因为您试图排队过多的线程.考虑切换到任务,并使用最大并发任务计划程序,您可以将其配置为限制一次运行多少个任务.然后用一个简单的 foreach循环遍历所有主机并为每个主机运行任务.当您达到并发限制时,循环将阻塞,直到可以计划任务为止.由于可以将限制设置得较低,这将使您可以更好地管理资源. (1000左右).它还消除了对您拥有的所有锁定代码的需要.

The reason you're resources are going up is because you're trying to enqueue way too many threads. Consider switching over to tasks and use a max concurrency task scheduler that you can configure to limit how many tasks are running at once. Then use a simple foreach loop to loop through all the hosts and run the task for each one. When you hit the concurrency limit the loop will block until the task can be scheduled. This will allow you to better manage your resources as you can set the limit to something low (1000 or something). It also eliminates the need for all that locking code that you have.

类似这样的东西( MSDN )可能会让您入门:

Something like this (MSDN) may get you started:

var hosts = GetHosts();
var tasks = new List<Task>();

//This sample comes from MSDN
var scheduler = var factory = new TaskFactory(new LimitedConcurrencyLevelTaskScheduler());

//This will loop through all hosts
foreach (var host in hosts)
{
   //At some point this will block until previous tasks have finished
   tasks.Add(factory.StartNew(() => DoPingWork(host)));
};

//Now just wait
Task.WaitAll(tasks.ToArray());

//Process any results

迈克尔·泰勒
http://www.michaeltaylorp3.net

Michael Taylor
http://www.michaeltaylorp3.net


这篇关于C#查找大型子网中的所有可用主机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆