C# 多线程:在线程之间传递不同的自定义控件属性(或异步使用它们)

C# 多线程:在线程之间传递不同的自定义控件属性(或异步使用它们),c#,winforms,C#,Winforms,我正在尝试开发一个项目,在这个项目中,我可以让多个客户机发出他们自己的服务器请求,以便进行压力测试。当我创建一个新线程并希望该线程完成工作时,我很难弄清楚如何操作自定义控件属性。我有超过100个控件;理想情况下,100名个人客户。问题是我的控件是GUI的一部分,我不知道如何允许有问题的线程从相对控件访问 以下是我所拥有的: // Custom project.class to get access to a custom base of properties created within

我正在尝试开发一个项目,在这个项目中,我可以让多个客户机发出他们自己的服务器请求,以便进行压力测试。当我创建一个新线程并希望该线程完成工作时,我很难弄清楚如何操作自定义控件属性。我有超过100个控件;理想情况下,100名个人客户。问题是我的控件是GUI的一部分,我不知道如何允许有问题的线程从相对控件访问

以下是我所拥有的:

    // Custom project.class to get access to a custom base of properties created within the tool itself.
        List<custom_control_project.custom_control_widget> controlList = new List<custom_control_project.custom_control_widget>();

    private async void btnStart_Click(object sender, EventArgs e)
        {
    ...// control property initializations

    foreach (var control in controlList)
                {
                    if (control.Enabled)
                    {
                        Thread thread = new Thread(() => StartClient());
                        thread.Start();

                        // Loop until worker thread activates.
                        while (!thread.IsAlive);

                        ... // Ideally the GUI updates would happen from these threads. Simple updates to labels based on status code responses and expected xml parameters received.
                    }
                 }
如何从传入方法的foreach语句中获得相对控制,然后根据结果修改GUI(以某种方式调用?)?此外,是否有可能使每个客户机独立,并同时具有多个客户机到服务器到客户机的请求?这是我的主要目标

如果这是一种牵强的或非常令人沮丧的尝试方式,请这样说。如果不钻研太多编程术语(为了理解目的,我对编程相当陌生),您将如何着手进行这项工作

提前谢谢

那么,您可以通过使用控件上的
BeginInvoke
函数,传递要执行的操作,从不同的线程对任何控件进行排序操作。该操作将在UI线程上执行

但你的主要问题是你没能做到。您的UI代码可以确保操作发生,但这些操作应该与任何UI代码不同。您应该以这样一种方式来设计您的操作,使其可重用。换句话说,如果您决定从头开始重写UI,您应该仍然能够按原样重用您的操作


为了实现这一点,您的操作不应该引用任何UI,甚至不应该知道任何UI的存在。这将使您的代码更易于管理。因此,在不同的类中提取所有这些内容,然后使用事件之类的东西与UI进行通信。然后,用户界面代码将进行
BeginInvoke
呼叫。

感谢您的回复。我将研究为此使用事件。我同意现在我的代码没有正确地分开。我想您的意思是,不需要来回传递相关的控件属性,只需在一个方法中完成所有处理并调用主GUI。我不知道如何在这个上下文中连接事件,但我会学习。你应该将数据封装到有意义的类中,并传递这些类,而不是传递UI控件。
public class StateObject
    {
        // Client socket.
        public Socket workSocket = null;
        // Size of receive buffer.
        public const int BufferSize = 1024;
        // Receive buffer.
        public byte[] buffer = new byte[BufferSize];
        // Received data string.
        public StringBuilder sb = new StringBuilder();
    }

        // ManualResetEvent instances signal completion.
        private ManualResetEvent connectDone =
            new ManualResetEvent(false);
        private ManualResetEvent sendDone =
            new ManualResetEvent(false);
        private ManualResetEvent receiveDone =
            new ManualResetEvent(false);

        // The response from the remote device.
        private String response = String.Empty;

        public void StartClient()
        {
            // Connect to a remote device.
            try
            {
                // Establish the remote endpoint for the socket.
                // The name of the
                // remote device is "host.contoso.com".
                //IPHostEntry ipHostInfo = Dns.Resolve("host.contoso.com");
                //IPAddress ipAddress = ipHostInfo.AddressList[0];
                //IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);

                // Create a TCP/IP socket.
                Socket client = new Socket(AddressFamily.InterNetwork,
                                           SocketType.Stream, ProtocolType.Tcp);

                // Connect to the remote endpoint.
                client.BeginConnect(asyncServerHolder, asyncPortHolder,
                                    new AsyncCallback(ConnectCallback), client);
                connectDone.WaitOne();

                // Send test data to the remote device.
                Send(client, (Upload)); //POST HTTP string + xml parameters
                sendDone.WaitOne();

                // Receive the response from the remote device.
                Receive(client);
                receiveDone.WaitOne();

                // Write the response to the console.
                //MessageBox.Show("Response received : " + response);

                // Release the socket.
                client.Shutdown(SocketShutdown.Both);
                client.Close();

                // Reset all manual events for next instance.
                connectDone.Reset();
                sendDone.Reset();
                receiveDone.Reset();
            }
            catch (Exception)
            {
                //MessageBox.Show(e.ToString());
            }
        }

        private void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object.
                Socket client = (Socket)ar.AsyncState;

                // Complete the connection.
                client.EndConnect(ar);

                //MessageBox.Show("Socket connected to " + client.RemoteEndPoint.ToString());

                // Signal that the connection has been made.
                connectDone.Set();
            }
            catch (Exception)
            {
                //MessageBox.Show(e.ToString());
            }
        }

        private void Receive(Socket client)
        {
            try
            {
                // Create the state object.
                StateObject state = new StateObject();
                state.workSocket = client;

                // Begin receiving the data from the remote device.
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                                    new AsyncCallback(ReceiveCallback), state);
            }
            catch (Exception)
            {
                //MessageBox.Show(e.ToString());
            }
        }

        private void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the state object and the client socket
                // from the asynchronous state object.
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.workSocket;

                // Read data from the remote device.
                int bytesRead = client.EndReceive(ar);

                if (bytesRead > 0)
                {
                    // There might be more data, so store the data received so far.
                    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

                    // Get the rest of the data.
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                                        new AsyncCallback(ReceiveCallback), state);
                }
                else
                {
                    // All the data has arrived; put it in response.
                    if (state.sb.Length > 1)
                    {
                        response1 = state.sb.ToString();
                    ///
                    ///
                    ///     **THIS IS WHERE I WANT ALL THE PROCESSING TO BE DONE**
                    ///     **AFTER THE RESPONSE IS COMPLETE!!**
                    ///
                    ///

                    }
                    // Signal that all bytes have been received.
                    receiveDone.Set();
                }
            }
            catch (Exception)
            {
                //MessageBox.Show(e.ToString());
            }
        }

        private void Send(Socket client, String data)
        {
            // Convert the string data to byte data using ASCII encoding.
            byte[] byteData = Encoding.ASCII.GetBytes(data);

            // Begin sending the data to the remote device.
            client.BeginSend(byteData, 0, byteData.Length, 0,
                             new AsyncCallback(SendCallback), client);
        }

        private void SendCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object.
                Socket client = (Socket)ar.AsyncState;

                // Complete sending the data to the remote device.
                int bytesSent = client.EndSend(ar);
                //MessageBox.Show("Sent " + bytesSent + " bytes to server.");

                // Signal that all bytes have been sent.
                sendDone.Set();
            }
            catch (Exception)
            {
                //MessageBox.Show(e.ToString());
            }
        }