Foreach冻结形式

时间:2015-12-31 00:15:12

标签: c# foreach scripting

我知道有很多关于foreach冻结形式的东西,但我无法找到解决问题的方法。我已经有这个程序的服务器部分正在工作我正在尝试建立一个客户端,在连接到服务器时,这个代码将被执行txtConn.AppendText("Attempting connection.");

这是我用于套接字连接的代码

private static Socket ConnectSocket(string server, int port, RichTextBox txtConn, BackgroundWorker backgroundWorker1)
    {
        Socket s = null;
        IPHostEntry hostEntry = null;

        // Get host related information.
        hostEntry = Dns.GetHostEntry(server);

        // Loop through the AddressList to obtain the supported AddressFamily. This is to avoid
        // an exception that occurs when the host IP Address is not compatible with the address family
        // (typical in the IPv6 case).
        backgroundWorker1.RunWorkerAsync();
        foreach (IPAddress address in hostEntry.AddressList)
        {
            IPEndPoint ipe = new IPEndPoint(address, port);
            Socket tempSocket =
                new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            Console.WriteLine(ipe);
            try
            {
                attempt++;
                txtConn.Select(txtConn.TextLength, 0);
                txtConn.SelectionColor = Color.Aqua;
                if (attempt == 1)
                {
                    txtConn.AppendText("Attempting connection.");
                }
                else if (attempt > 1)
                {
                    txtConn.AppendText("\r" + "Attempting connection.");
                }
                txtConn.SelectionColor = txtConn.ForeColor;
                tempSocket.Connect(ipe);
            }
            catch (ArgumentNullException ane)
            {
                Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
                txtConn.Select(txtConn.TextLength, 0);
                txtConn.SelectionColor = Color.Red;
                txtConn.AppendText("\r\n" + "Connection could not be established.");
                txtConn.SelectionColor = txtConn.ForeColor;
            }
            catch (SocketException se)
            {
                Console.WriteLine("SocketException : {0}", se.ToString());
                txtConn.Select(txtConn.TextLength, 0);
                txtConn.SelectionColor = Color.Red;
                txtConn.AppendText("\r\n" + "Connection could not be established.");
                txtConn.SelectionColor = txtConn.ForeColor;
            }
            catch (Exception e)
            {
                Console.WriteLine("Unexpected exception : {0}", e.ToString());
                txtConn.Select(txtConn.TextLength, 0);
                txtConn.SelectionColor = Color.Red;
                txtConn.AppendText("\r\n" + "Connection could not be established.");
                txtConn.SelectionColor = txtConn.ForeColor;
            }

            if (tempSocket.Connected)
            {
                Console.WriteLine("Connected");
                s = tempSocket;
                break;
            }
            else
            {
                continue;
            }
        }
        return s;
    }

My program looks like this

当我运行程序并连接错误的端口时,它会检查我的计算机上的所有可能的ips并等到foreach语句后显示错误或任何内容。如何让它主动显示?This is when it runs

3 个答案:

答案 0 :(得分:0)

您需要在不同的线程中运行代码,以便UI在执行时仍然可以更新。

最简单的方法是将连接循环添加到ThreadPool中的新任务。

ThreadPool.QueueUserWorkItem(i => {
    // Connection loop goes here.
});

如果您需要other options,还可以使用Task,BackgroundWorker等

答案 1 :(得分:0)

使用应该使用Async类中的Socket方法,或者在另一个线程中运行这些东西。您也可以使用BackgroundWorker来执行此操作。

答案 2 :(得分:0)

我刚刚回答了类似的问题here,但为了适应您的具体情况,我们似乎并没有真正使用backgroundWorker1。 foreach应该在backgroundWorker1.DoWork事件引用的方法中完成。您还需要为backgroundWorker1.ProgressChanged事件创建一个方法。您可以使用ReportProgress传递字符串,然后将该消息附加到文本框中:

从Worker_DoWork方法的foreach循环中,您将报告进度,而不是直接更新RichTextBox:

worker.ReportProgress(0, "Connection could not be established.");

然后在Worker_ProgressChanged方法中,您将使用类似的东西来更新RichTextBox:

txtConn.AppendText(e.UserState.ToString());