简体   繁体   中英

When do i need to dispose a (server-client) objects?

in server -(multi)client application [TCP]. I use Socket, NetworkStream, StreamReader and StreamWriter for each client i Accept in the server .. so i have couple of questions :

  • Do i have to dispose all of them when i want to close the connection with a client?
  • If the client Disposes the Socket that's connected with the server .. do i also have do dispose that socket in the server side ,or it closes automatically ?
  • in my code here :

      Thread thAccept = new Thread(acceptClient); Thread thJob; private void acceptClient() { while (true) { Socket client = server.Accept(); Console.WriteLine(client.RemoteEndPoint+" has connected"); StreamReader reader = new StreamReader(new NetworkStream(client)); //is it ok to create an instance NetworkStream like this or i will have to dispose it later? thJob = new Thread(Job); thJob.Start(reader); } } private void Job(object o) { StreamReader reader = (Socket)o; try { string cmd = null; while ((cmd = reader.ReadLine()) != null) { //(BLA BLA..) } } catch { Console.WriteLine("Disconnected by catch"); } finally { Console.WriteLine("Finally Done."); reader.Dispose(); } } 

    is that code fine to dispose all (needed to be disposed) objects?

  • This is not a duplicate.

    Your code differs from the linked duplicate because in your code, the IDisposable is handed off to another thread.

    The general rule is that if you create an object that implements IDisposable , then you're responsible for calling Dispose on it when you're finished with it. When possible, that should be done in a using block, to ensure that Dispose is always called. In your case, your code is not finished with the object until the other thread is exited. In that thread, you correctly call Dispose in the finally block.

    If you had called Dispose on the NetworkStream , then it would have closed the StreamReader as well, which would defeat your purpose. I suspect it would be the same thing if you had called Dispose on the Socket . As such, your code is correct as-is.

    The object on the client side has no relationship with the object on the server side, except through TCP/IP. The fact that the client may call Dispose on its socket doesn't mean that the server has to call Dispose on its socket. However, once the server is finished reading data from the socket, and the connection is closed, the server-side socket should be Disposed . I don't know for certain, but I believe that when the StreamReader is disposed, the underlying NetworkStream will be disposed, which should call Dispose on the socket from which the stream was created.

    Your code is fine, except for some unrelated issues: you don't need to set cmd to null , since you're going to set the value in the next statement. Also, you should not use an empty catch block like that. You have no idea what exception was thrown, but you will ignore it anyway, without even logging or displaying the exception. At the least, you should do

        catch (Exception ex)
        {
    
            Console.WriteLine("Disconnected by exception " + ex.ToString());   
        } 
        finally 
        {  
            Console.WriteLine("Finally Done."); 
            reader.Dispose(); 
        } 
    

    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