Is there any way to have immutable parameters in a C# method? Below I have some code for a messenger application that is giving me some issues. The idea is that there is one server that can handle multiple clients. The code works by creating a TcpListener
that watches for incoming connections, getting the IP address of the underlying TcpClient
(which is sent through the NetworkStream
as a string), starting a new thread which will handle messages from that client, and then listening for more connections. The main problem is that after the client
object is passed into the new Thread
, the main code loops around and sets the value of client
to null
while waiting for another connection.
Error type: System.InvalidOperationException
Error message: The operation is not allowed on non-connected sockets.
What this says to me is that the TcpClient
's value inside the handleMessages
thread is being affected by what happens to client
after the thread is initiated by the .Start()
method.
Here's my code:
private void watchForConnections()
{
TcpListener listener = new TcpListener(IPAddress.Any, this.Port); //Listener that listens on the specified port for incoming clients
listener.Start();
TcpClient client = new TcpClient();
do
{
client = listener.AcceptTcpClient(); //Wait for connection request
StreamReader reader = new StreamReader(client.GetStream());
string clientIP = reader.ReadLine(); //Use the StreamReader to read the IP address of the client
RelayMessage("SERVER_NEW_" + clientIP + "_" + DateTime.Now.ToString("HH:mm:ss")); //Tell all machines who just connected
Thread messageWatcher = new Thread(() => handleMessages(client));
messageWatcher.Start(); //Start new thread to listen for messages from that specific client
} while (AllowingConnections == true);
listener.Stop();
}
private void handleMessages(TcpClient _client)
{
using (StreamReader readMsg = new StreamReader(_client.GetStream())) //I get the error here
using (StreamWriter writeMsg = new StreamWriter(_client.GetStream())) //And here
{
//Handle messages from client here
}
}
My question: is there any way to have a parameter in handleMessages
that will not be affected by what happens OUTSIDE of the method? My research so far has turned up nothing about this, or anything like it. What I need is kind of like the opposite of a ref
parameter. Maybe I'm just not searching the right things. I don't know if I'm even explaining it right.
Another example with strings:
string data = "hello";
Thread doStuff = new Thread(() => DoStuff(data)); //Value of data is equal to: "hello"
doStuff.Start();
data = "goodbye"; //I want the value of the string in the doStuff thread to still be: "hello", not "goodbye" (Don't reflect changes made to string after thread is started/method is called)
If anything's not clear, please let me know! I'm probably just as confused as you!
UPDATE/SOLUTION: For anyone who needs it in the future, this is how the problem was resolved, as per Viru's answer:
Thread messageWatcher = new Thread(() => handleMessages(client.Clone());