线程和多线程问题

时间:2014-07-19 10:37:38

标签: c# multithreading thread-safety

我正在构建扫描IP地址的程序。我构建了一个检查

端口的类

给定的IP地址。我在循环中将此类作为线程运行。我显然阻止了

的数量

可以并行运行的线程。问题是线程总是返回一个退出

代码:259,大约半分钟后,程序挂起。

我尝试在谷歌,论坛中搜索,这里代码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 个答案:

答案 0 :(得分:0)

Get_Port_With_Status_Thread_Inventer中的for循环实际上阻止了当前调用它的线程,直到你完成处理ip地址为止。无论何时需要在C#中使用多线程,都应该使用tasks代替。

对于您的问题,您最好使用parallel foreach loop

    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类有助于保持IPAddress与程序是否可以连接到端口80同步。 IsAlive的默认值为null。您无需担心将索引从一个线程传递到下一个线程。

答案 1 :(得分:-1)

解决方案很简单。不要使用调试器运行多个线程,所以如果你有Microsoft

Visual Studio,你想要运行很多线程,在没有调试器的情况下运行程序!