C# Ping работает недостаточно быстро

Я пытаюсь выполнить сканирование, находится ли компьютер в сети или в автономном режиме. Но мой текущий код - это способ замедлить сканирование с хорошей производительностью, как если бы компьютер отключен, есть задержка от 3 до 5 секунд. Я даже добавил параметр тайм-аута, равный 500, но это все равно занимает более 3 секунд, если компьютер отключен.

public bool PingComputer(string computername)
    {
        bool check = false;
        Ping ping = new Ping();
        try
        {
            PingReply reply = ping.Send(computername, 500);
            check = reply.Status == IPStatus.Success;
        }
        catch (PingException)
        {

        }
        return check;
    }

Я также уже читал об асинхронных пингах, но пока не смог найти подходящего решения, которое просто возвращает true, если компьютер подключен к сети, или false, если он отключен.

Заранее спасибо.

Ваш код слишком медленный, потому что вы проверяете один компьютер за раз? Почему бы не сделать параллельный foreach, если нет? Если это все еще не так, создайте свой собственный класс ping, который не пытается повторять попытки и возвращает false при коротком тайм-ауте tcp-соединения.

Sam Marion 11.04.2018 22:30

посмотри на это: stackoverflow.com/questions/49069381/…

Ji Ra 11.04.2018 23:02

сколько компьютеров вы пингуете

TheGeneral 12.04.2018 00:36

Имя компьютера требует преобразования DNS в IP-адрес. Вы должны кэшировать результат DNS, если хотите его ускорить. Изучите протоколы DNS и ICMP, если вы еще этого не сделали.

Lex Li 12.04.2018 01:12

Вам нужно более точное определение «онлайн». Ping может работать для одного IP-адреса, но не для другого, в зависимости от настроек брандмауэра. Это может работать с именем системы, но не с ее адресом, в зависимости от DNS-серверов. Он может вообще не работать, пока HTTP работает, опять же, в зависимости от настроек брандмауэра. Я предлагаю проверить что-то более конкретное, например, доступ к определенному сайту

Ray Fischer 12.04.2018 01:21

Командная строка ping работает быстрее для то же имя компьютера, когда C# Ping медленный? Я подозреваю, что ваша проблема не имеет никакого отношения к C# Ping, и все это связано с ping IP / ICMP.

Remus Rusanu 12.04.2018 07:39
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
816
1

Ответы 1

Если вы сделали вид, что пропингуете список компьютеров, вы можете использовать Parallel или асинхронный Task.

Я протестировал оба метода ниже с одинаковыми 77 IP-адресами. Использовалась переменная sec = 3.

  • Toke задач 00: 00: 02.7146249
  • Параллельный ток 00:00: 05.9941404

Использовать методы

Dictionary<string, bool> pingsReturn = await Network.PingListAsync(dictionary,3);

Я могу привести два примера:

Задача

public static async Task<Dictionary<string, bool>> PingListAsync(Dictionary<string, bool> HostList, int sec = 3)
        {

            // Create a buffer of 32 bytes of data to be transmitted.
            string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
            byte[] buffer = Encoding.ASCII.GetBytes(data);
            // set a quick TTL
            PingOptions options = new PingOptions(20, true);

            // internal support Task to handle Ping Exceptions like "host not found"
            async Task<KeyValuePair<string, bool>> PingHost(string host)
            {
                try
                {
                    var pingresult = await Task.Run(() => new Ping().SendPingAsync(host, sec * 1000, buffer, options));
                    //t.Wait();
                    if (pingresult.Status == IPStatus.Success)
                        return new KeyValuePair<string, bool>(host, true);
                    else
                        return new KeyValuePair<string, bool>(host, false);

                }
                catch
                {
                    return new KeyValuePair<string, bool>(host, false);
                }

            }

            //Using Tasks >>
            var watch = new Stopwatch();
            watch.Start();
            var tasksb = HostList.Select(HostName => PingHost(HostName.Key.ToString()));

            var pinglist = await Task.WhenAll(tasksb);


            foreach (var pingreply in pinglist)
            {
                HostList[pingreply.Key] = pingreply.Value;
            }

            watch.Stop();
            Log.Debug("PingList (Tasks) Time elapsed: " + watch.Elapsed);
            //Using Tasks <<



            return HostList;

        }

Параллельный

public static async Task<Dictionary<string, bool>> PingListAsync(Dictionary<string, bool> HostList, int sec = 3)
        {

            // Create a buffer of 32 bytes of data to be transmitted.
            string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
            byte[] buffer = Encoding.ASCII.GetBytes(data);
            // set a quick TTL
            PingOptions options = new PingOptions(20, true);

            //Using Parallel >>
            watch = new Stopwatch();
            watch.Start();

            // avoid exception "Collection was modified; enumeration operation may not execute."
            // we need new dictionary and add values
            Dictionary<string, bool> dictionary = new Dictionary<string, bool>();
            Parallel.ForEach(HostList.Keys, (currHost) =>
            {

                try
                {
                    var pingReply = new Ping().Send(currHost, sec * 1000, buffer, options);
                    if (pingReply.Status == IPStatus.Success)
                        dictionary.Add(currHost, true);
                    else
                        dictionary.Add(currHost, false);
                }
                catch
                {
                    // handle Ping Exceptions like "host not found"
                    dictionary.Add(currHost, false);
                }


            });
            watch.Stop();
            Log.Debug("PingList (Parallel) Time elapsed: " + watch.Elapsed);
            //Using Parallel <<

            return dictionary;

        }

PS - Я знаю, что это старый вопрос, но он все еще актуален.

Другие вопросы по теме