Тема с многопоточностью

Я создаю программу для сканирования IP-адресов. Я построил класс, который проверяет порты

данный IP-адрес. Я запускаю этот класс в цикле как поток. Я, очевидно, блокирует количество

поток, который может быть запущен параллельно. Проблема в том, что всегда поток возвращает выход

код: 259, и примерно через полминуты программа зависает.

Я пытался искать в Google, форумах, и вот, что означает код 259. Так что я нашел в некоторых

форумы, которые просто возвращают код, который ничего не значит. На других форумах я вижу, что это

означает, что есть проблема с использованием большого количества памяти. Поэтому я стараюсь использовать только 2 темы

Параллель. Это все еще не работает. Я пытаюсь увидеть другие методы для работы с потоками, поэтому я читаю

Что касается пула потоков, я изменяю код для использования пула потоков, но он все еще не работает. Я из

Конечно, убедился, что в классе я не использую глобальные переменные.

Код:

   private void Get_Port_With_Status_Thread_Inventer()
    {

        for (int Thread_Cnt_Get_Port_N_Status = 1; Thread_Cnt_Get_Port_N_Status < IP_Address.Length + 1; Thread_Cnt_Get_Port_N_Status++)
        {

            if (Open_Threads_Port_N_Status_Counter >= Max_Thread_Allowed)
            {
               Thread_Cnt_Get_Port_N_Status--;
               continue;
            }

            Thread New_Port_N_Status_Thread = new Thread(new ParameterizedThreadStart(Get_Port_With_Status_Thread));
            New_Port_N_Status_Thread.Start(Thread_Cnt_Get_Port_N_Status);

            Open_Threads_Port_N_Status_Counter++;
        }

        End_Get_Port_N_Status_Inventer = true;
    }

   private void Get_Port_With_Status_Thread(object Index_On_Array_Obj)
    {

        int Index_On_Array = (int)Index_On_Array_Obj;

        string IP_Address_Str = IP_Address[Index_On_Array - 1];


        IPEndPoint IP_Address_Connect_Data_Base = new IPEndPoint(IPAddress.Parse(IP_Address_Str), 80);

        Socket Socket_IP_Address_Connect_Data_Base = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        string Ports_Rep_Index = 80.ToString();

        DateTime Current_New_Now_Seconds = DateTime.Now.Date;

        try
        {
            Socket_IP_Address_Connect_Data_Base.Connect(IP_Address_Connect_Data_Base);
            Socket_IP_Address_Connect_Data_Base.Disconnect(true);

            IP_Port[Index_On_Array - 1] = "Port 80 - Live";
        }

        catch (SocketException g)
        {
            IP_Port[Index_On_Array - 1] = "Port 80 - Dead";
        }

        Open_Threads_Port_N_Status_Counter--;
    }

2 ответа

Решение

Решение было просто. Не запускайте несколько потоков с помощью отладчика, так что если у вас есть Microsoft

Visual Studio и вы хотите запустить много потоков, запустите программу без отладчика!

Ваш цикл for в Get_Port_With_Status_Thread_Inventer по сути блокирует текущий поток, к которому он был вызван, до тех пор, пока вы не закончите обработку IP-адресов. В любое время вам нужно использовать многопоточность в C#, вместо этого вы должны использовать задачи.

Для вашей проблемы лучше использовать параллельный цикл foreach:

    class Status
    {
        public IPAddress IpAddress { get; set; }
        public bool? IsAlive { get; set; }
    }

    private Status[] ipAddresses = new Status[]
    {
        new Status()
        {
            IpAddress = IPAddress.Parse("192.168.1.1")
        },
        new Status()
        {
            IpAddress = IPAddress.Parse("192.168.1.2")
        },
        new Status()
        {
            IpAddress = IPAddress.Parse("192.168.1.3")
        },
    };



    private void scanPorts()
    {
        Parallel.ForEach(ipAddresses, scanPort);
    }

    private void scanPort(Status status)
    {
        IPEndPoint ipEndPoint = new IPEndPoint(status.IpAddress, 80);
        Socket socket = new Socket(AddressFamily.InterNetwork,
                                   SocketType.Stream,
                                   ProtocolType.Tcp);

        try
        {
            socket.Connect(ipEndPoint);
            socket.Disconnect(true);

            status.IsAlive = true;
        }
        catch (SocketException)
        {
            status.IsAlive = false;
        }
    }

Метод Parallel.ForEach принимает IEnumerable (например, массив или список) и вызывает метод для каждого элемента массива в своем собственном потоке. Библиотеки.NET управляют созданием, запуском и уничтожением потоков для вас. Единственное, о чем вам нужно беспокоиться, это о том, как правильно распределить ваши данные между потоками.

Созданный класс Status помогает поддерживать синхронизацию IP-адреса с тем, может ли программа подключаться к порту 80 или нет. Значение по умолчанию для IsAlive равно нулю. Вам не нужно беспокоиться о передаче индекса из одного потока в другой.

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