1

I know there are plenty of things about foreach freezing forms but I can't find a solution to my problem. I already have the server portion of this program working I am trying to make a client side that while connecting to the server this code will be preformed txtConn.AppendText("Attempting connection.");

This is the code that I have for the socket 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

When I run the program and connect with say the wrong Port, it checks all the possible ips on my computer and waits till after the foreach statement to display errors or anything. How can I make it actively display this?This is when it runs

Ghasem
  • 14,455
  • 21
  • 138
  • 171
MattG5TK
  • 11
  • 2
  • *foreach freezing forms*? Are you talking about the program becoming unresponsive? Sounds like you need to read up about `Thread`s. – Luke Joshua Park Dec 31 '15 at 00:19
  • I see that you already have a background worker. What code does it execute? Why don't you put the for loop inside the background work DoWork event handler? – Yacoub Massad Dec 31 '15 at 00:19

3 Answers3

1

You need to run your code in a different thread so that the UI can still update while it is executing.

The easiest way to do this is by adding the connection loop to a new task in the ThreadPool.

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

If you need other options you can also use a Task, BackgroundWorker, etc.

Community
  • 1
  • 1
Cyral
  • 13,999
  • 6
  • 50
  • 90
0

Use should use Async methods from Socket class or run this stuff in another thread. You can use BackgroundWorker to do that as well.

Cleiton
  • 17,663
  • 13
  • 46
  • 59
0

I just answered a similar question here, but to expand on it for your particular case, it looks like you aren't actually using backgroundWorker1. The foreach should be done in a method referenced by the backgroundWorker1.DoWork event. You'll also need to create a method for the backgroundWorker1.ProgressChanged event. You can use ReportProgress to pass a string and then append that message to your textbox:

From your foreach loop in the Worker_DoWork method, you will report progress instead of updating the RichTextBox directly:

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

And then in the Worker_ProgressChanged method, you will use something like this to update the RichTextBox:

txtConn.AppendText(e.UserState.ToString());
Community
  • 1
  • 1
Tim
  • 857
  • 6
  • 13
  • How can I append the string to a richtextbox? – MattG5TK Dec 31 '15 at 00:48
  • In your foreach loop, you'll be calling worker.ReportProgress with a message instead of updating the RichTextBox directly. So, in the Worker_ProgressChanged method, you'll do something like txtConn.AppendText(e.UserState.ToString()). I'll update the answer to reflect that. – Tim Dec 31 '15 at 01:01
  • Thank you this helped more than anything else. Thanks Tim. – MattG5TK Dec 31 '15 at 01:14