线程和多线程问题
本文关键字:问题 多线程 线程 | 更新日期: 2023-09-27 18:13:41
我正在构建一个扫描IP地址的程序。我构建了一个类来检查
的端口给定的IP地址。我将这个类作为线程在循环中运行。很明显我阻塞了
的数量可以并行运行的线程。问题是线程总是返回一个exit
code: 259,大约半分钟后,程序挂起。
我试着在谷歌、论坛和这里搜索代码259意味着什么。所以我发现在一些
论坛,它只是返回代码,没有任何意义。在其他论坛我看到的是
表示使用大量内存存在问题。所以我尝试在
中只使用2个线程paralel。还是不行。我试图看到其他方法与线程一起工作,所以我读取
关于线程池,我改变代码使用线程池,但它仍然不工作。I (
)课程确保在课堂上我不使用全局变量
代码:
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--;
}
Get_Port_With_Status_Thread_Inventer中的for循环本质上是阻塞当前被调用的线程,直到您完成处理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;
}
}
平行。ForEach方法接受一个IEnumerable(如数组或列表),并在它自己的线程中为数组中的每个元素调用一个方法。. net库为你处理线程的创建、运行和销毁。你唯一需要担心的是如何在线程之间正确地共享数据。
我所做的Status类有助于保持IPAddress与程序是否可以连接到端口80同步。IsAlive的缺省值为空。您不需要担心将索引从一个线程传递到下一个线程。
解决方案很简单。不要用调试器运行多线程,所以如果你有Microsoft
Visual Studio和你想运行很多线程,运行程序没有调试器!