线程和多线程问题

本文关键字:问题 多线程 线程 | 更新日期: 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和你想运行很多线程,运行程序没有调试器!