【问题标题】:Foreach freezing formForeach 冷冻表格
【发布时间】:2016-04-05 00:04:30
【问题描述】:

我知道有很多关于 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

【问题讨论】:

  • foreach 冻结表格?您是在谈论程序变得反应迟钝吗?听起来您需要阅读有关Threads 的信息。
  • 我看到您已经有一个后台工作人员。它执行什么代码?为什么不将 for 循环放在后台工作 DoWork 事件处理程序中?

标签: c# foreach scripting


【解决方案1】:

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

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

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

如果你需要other options,你也可以使用Task、BackgroundWorker等

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      我刚刚回答了一个类似的问题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());
      

      【讨论】:

      • 如何将字符串附加到富文本框?
      • 在您的 foreach 循环中,您将使用消息调用 worker.ReportProgress,而不是直接更新 RichTextBox。因此,在 Worker_ProgressChanged 方法中,您将执行类似 txtConn.AppendText(e.UserState.ToString()) 的操作。我会更新答案以反映这一点。
      • 感谢您的帮助。谢谢蒂姆。
      猜你喜欢
      • 1970-01-01
      • 2016-04-10
      • 2016-03-14
      • 1970-01-01
      • 1970-01-01
      • 2020-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多