Тема с многопоточностью
Я создаю программу для сканирования 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 равно нулю. Вам не нужно беспокоиться о передаче индекса из одного потока в другой.