简体   繁体   English

什么时候需要处置(服务器-客户端)对象?

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

in server -(multi)client application [TCP]. 在服务器-(多)客户端应用程序[TCP]中。 I use Socket, NetworkStream, StreamReader and StreamWriter for each client i Accept in the server .. so i have couple of questions : 我为服务器中接受的每个客户端使用Socket,NetworkStream,StreamReader和StreamWriter ..所以我有几个问题:

  • 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. 您的代码与链接的重复项有所不同,因为在您的代码中, IDisposable已移交给另一个线程。

    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. 通常的规则是,如果您创建一个实现IDisposable的对象,那么您需要在完成Dispose在其上调用Dispose When possible, that should be done in a using block, to ensure that Dispose is always called. 如果可能,应在using块中完成此using ,以确保始终调用Dispose 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. 在该线程中,您可以在finally块中正确调用Dispose

    If you had called Dispose on the NetworkStream , then it would have closed the StreamReader as well, which would defeat your purpose. 如果您在NetworkStream上调用了Dispose ,那么它也将关闭StreamReader ,这将使您无法达到目的。 I suspect it would be the same thing if you had called Dispose on the Socket . 我怀疑如果您在Socket上调用Dispose也是一样。 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. 客户端上的对象与服务器端上的对象没有关系,除非通过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. 客户端可以在其套接字上调用Dispose的事实并不意味着服务器必须在其套接字上调用Dispose However, once the server is finished reading data from the socket, and the connection is closed, the server-side socket should be Disposed . 但是,一旦服务器完成了从套接字读取数据并关闭了连接,则服务器端套接字应该被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. 我不确定,但是我相信当StreamReaderStreamReader时,底层的NetworkStream将被释放,它应该在创建流的套接字上调用Dispose

    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. 您的代码很好,除了一些无关的问题:您无需将cmd设置为null ,因为您将在下一条语句中设置值。 Also, you should not use an empty catch block like that. 另外,您不应使用空的catch块。 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(); 
        } 
    

    声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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