-2

I'm making a multithreaded chat server and chat client. The client has a Form1 called Login and a Form2 called MainProgram. The following code is from "Login". What I'm trying to do is transitioning from Login to MainProgram...

        MainProgram mP = new MainProgram(clientSocket, username);
        mP.Closed += (s, args) => this.Close();
        this.Hide();
        mP.ShowDialog();
        mP.Show();

... however. When assigning mP MainProgram mP = new MainProgram(clientSocket, username); The code get's stuck in the thread specified here:

public MainProgram(TcpClient c, string u)
    {
        InitializeComponent();
        try
        {
            serverStream = c.GetStream();
            clientSocket = c;
            username = u;
            new Thread(Receive()) { IsBackground = true }.Start();
        }

Here is the Thread:

        private ThreadStart Receive()
    {
        while (true)
        {
            try
            {
                byte[] inStream = new byte[1024];
                serverStream.Read(inStream, 0, inStream.Length);
                string returndata = Encoding.ASCII.GetString(inStream);
                returndata = returndata.Substring(0, returndata.IndexOf("$"));
                Msg($"{returndata}");
            }
            catch(Exception e)
            {
                MessageBox.Show($"{e.Message}\n\n{e.ToString()}");
            }
        }
    }

Please note that the thread is supposed to be running this while loop indefinitely, but in the background. Right now it doesn't make a new thread and runs on the MainThread. The problem is that i don't know how to start this thread without making the client get stuck in this while loop. And not transitioning.

Adam
  • 1
  • 3
  • Your `MainProgram` function should not call `Receive`. – David Schwartz May 17 '18 at 21:01
  • then how do i start the thread? – Adam May 17 '18 at 21:21
  • How do you know that your program stuck in this thread? – Sergey L May 17 '18 at 21:26
  • By debugging. I put a breakpoint in the loop and debug with stepping. It seems like i only have one thread. In the drop-down menu at the top when debuggin i only have MainThread – Adam May 17 '18 at 21:28
  • Why is your `Recieve` method defined as a *returning* a value of type `ThreadStart`? – pinkfloydx33 May 17 '18 at 21:44
  • @Eser It does compile. The compiler is smart enough to see that there's an infinite loop and that a return value is therefore not needed – Kevin Gosse May 18 '18 at 06:10
  • Don't ever code `catch(Exception e)` - it's a terrible practice that swallows errors and causes bugs in your code. Your code will, if this exception is caught, try to create a UI element on a non-UI thread - your should never do that. You should only ever catch specific exceptions that can be meaningfully handled. – Enigmativity May 20 '18 at 12:33

1 Answers1

1

It seems you didn't understand what is ThreadStart. This is the signature of the method that is accepted to create a thread.

When you call:

new Thread(Receive()) 

You're actually calling the "Receive" method in the main thread, and giving its return value to the thread constructor (which never happens because it's stuck in your infinite loop.

Instead you need to do

new Thread(new ThreadStart(Receive))

Mind the removed parenthesis.

But then you'll get a compilation error because your Receive method doesn't have the right signature. So you need to change it into:

private void Receive()
{
    // ...
}
Kevin Gosse
  • 38,392
  • 3
  • 78
  • 94
  • I didn't mention it in the answer to avoid confusion, but note that `new Thread(new ThreadStart(Receive))` can be shortened into `new Thread(Receive)` (the `new ThreadStart` is automatically added by the compiler) – Kevin Gosse May 17 '18 at 21:45
  • The main problem, according to a classmate was that i used () after my function which means I am waiting for a return value. Right now i am using "`new Thread(ReceiveThread).Start();`" and it works fine :) – Adam May 18 '18 at 18:38