简体   繁体   中英

Using Block with Threading

I'm reasonably experienced with C#, however I've never come across this problem before, and I was wondering if any more experienced C# Developers know what to do in this situation. Here's the code for the method in question: (the problem is explained after the block of code)

public void ConnectToRemoteServer() 
{
    Console.WriteLine("Attempting to connect to " + config.GetString(ConfigParams.MasterServerIp) + ":" + config.GetString(ConfigParams.MasterServerPort));
    TcpClient client = new TcpClient();
    IPEndPoint address = new IPEndPoint(IPAddress.Parse(config.GetString(ConfigParams.MasterServerIp)), config.GetInt(ConfigParams.MasterServerPort));
    Console.WriteLine("Connecting...");
    //Begin asynchronous sever communication
    if (this.autoTask == null)
    {
        communicator = new CommunicationListener(client, config, address);
    }
    else
    {
        communicator = new CommunicationListener(client, config, address, this.autoTask);
    }
    Thread communicationThread = new Thread(new ThreadStart(communicator.Start));
    communicationThread.Start();
}

The part that I'm wondering about is if I should be using a using statement in this block of code. I know that TcpClient implements the interface IDisposable , and as such should be encapsulated in a using statement, however, in this case, a new thread is started that uses the TcpClient , and as such the end of the using block will be reached before the TcpClient is done being used. So should I be using the using statement here?

Don't use using here as it will make your program not work due to early disposal. Just make sure you hand off the TcpClient correctly to the new thread and make sure the thread disposes of it eventually.

I think it would be preferable to create the TcpClient in the child thread so you can use using there.

I think you are right to avoid the using block in this case since using results in an implicit close() at the end of the using block. I think this is a fairly common source of aggravation because the usual advice on when to use using blocks is "whenever the object impliments IDisposable".

Here is a definitive article on when NOT to use using, regardless of the implementation of IDisposable. http://msdn.microsoft.com/en-us/library/aa355056.aspx .

The general rule of thumb is that if its IDisposable then you should dispose of that object.

A using block gives you a nice easy way to do that, but since your TCPClient will persist outside of this method, then it cant be used in this case.

If you really wanted to write nice code then should; declare your TCPClient within your class, have your class implement IDisposable, dispose of your TCPClient within your new Dispose method. (and maybe do something about ending your thread).

That way you can wrap your class within using block.

I think there is a different kind of problem. You have to implement IDisposable in CommunicationListener and instantiate the TcpClient also there and dispose the TcpClient in the CommunicationListener.Dispose implementation.

When would be better to dispose CommunicationListener? It depends.

I would make the class in which this method exists and CommunicationListener both disposable. Then I would implement a way to cancel the communication listener's thread by setting a flag on it so that when your own class is disposed, it doesn't leave the other thread running. Then in the Dispose of the parent class, set the flag so CommunicationListener can stop, dispose of the CommunicationListener, which should then internally dipose of the TcpClient.

I hope that makes sense.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM