在服务器 - (多)客户端应用程序[TCP]中。我为服务器中的每个客户端使用Socket,NetworkStream,StreamReader和StreamWriter ..所以我有几个问题:
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();
}
}
是处理所有(需要处置)对象的代码吗?
答案 0 :(得分:0)
这不重复。
您的代码与链接的副本不同,因为在您的代码中,IDisposable
会移交给另一个帖子。
一般规则是,如果您创建一个实现IDisposable
的对象,那么当您完成它时,您有责任在其上调用Dispose
。如果可能,应该在using
块中完成,以确保始终调用Dispose
。在您的情况下,您的代码不会与对象一起完成,直到退出另一个线程。在该主题中,您正确地在Dispose
块中调用了finally
。
如果您在Dispose
上调用NetworkStream
,那么它也会关闭StreamReader
,这会破坏您的目的。我怀疑如果你在Dispose
上调用了Socket
,那将是同样的事情。因此,您的代码按原样正确。
客户端上的对象与服务器端的对象没有关系,除非通过TCP / IP。客户端可能在其套接字上调用Dispose
这一事实并不意味着服务器必须在其套接字上调用Dispose
。但是,一旦服务器完成从套接字读取数据,并且连接已关闭,服务器端套接字应为Disposed
。我不确定,但我相信当StreamReader
被处置时,将放置基础NetworkStream
,这应该在创建流的套接字上调用Dispose
您的代码很好,除了一些不相关的问题:您不需要将cmd
设置为null
,因为您将在下一个语句中设置该值。此外,您不应该使用这样的空catch
块。你不知道抛出了什么异常,但无论如何你都会忽略它,甚至不记录或显示异常。至少,你应该做
catch (Exception ex)
{
Console.WriteLine("Disconnected by exception " + ex.ToString());
}
finally
{
Console.WriteLine("Finally Done.");
reader.Dispose();
}