为什么流上的“Close”调用在C#和Java中表现不同?

时间:2022-10-21 06:37:03

Consider the following scenario, a servlet has been written in Java and once you connect to the servlet, it starts writing to the OutputStream, let's say 10 million bytes, 1 byte at a time.

考虑以下场景,一个servlet是用Java编写的,一旦你连接到servlet,它就会开始写入OutputStream,比方说1000万字节,一次1个字节。

You have a client program which reads the servlet's response stream and reads say 100 bytes and calls close. Now if your client program is in Java, the streams close immediately and the server stops sending the content, but if the client program is in C#, the close call takes a long time to finish because it apparently waits for server to finish writing all the 10 million bytes.

你有一个客户端程序,它读取servlet的响应流并读取100字节并调用close。现在,如果您的客户端程序是Java,则流立即关闭,服务器停止发送内容,但如果客户端程序在C#中,则关闭调用需要很长时间才能完成,因为它显然等待服务器完成所有的写入1000万字节。

So, I have two questions on this,

所以,我有两个问题,

  1. Why does C# behave differently?
  2. 为什么C#表现不同?

  3. What can I do to ensure the Close call on the C# stream closes the stream immediately and does not allow the server to keep sending the data?
  4. 我该怎么做才能确保C#流上的Close调用立即关闭流并且不允许服务器继续发送数据?

Any pointers will be greatly appreciated :-)

任何指针将不胜感激:-)

2 个解决方案

#1


3  

I'm assuming sockets of some kind here. I would suspect that the Java implementation is simply closing the client socket, possibly causing an error on the server, whilst the C# version is being slightly more friendly to the server and waiting for it to acknowledge a close request. Since the server is busy firing off data, it doesn't get - or at least doesn't process - the close request until it's finished sending.

我在这里假设某种插座。我怀疑Java实现只是关闭客户端套接字,可能导致服务器上的错误,而C#版本对服务器稍微友好并等待它确认关闭请求。由于服务器忙于触发数据,因此在完成发送之前,它不会 - 或者至少不会处理 - 关闭请求。

Think of it this way: somebody at your front door trying to sell you something and won't be interrupted. You can slam the door in their face which shuts them up immediately, or you can wait until they've finished talking and then ask them to leave.

可以这样想:你前门的某个人试图卖给你一些东西而且不会被打断。你可以将门砰地一声关上,然后立即关闭它们,或者你可以等到他们说完话然后让他们离开。

To solve it, perhaps you could create a worker thread that opens the stream, waits for the 100 bytes, then closes. In the meantime your program can do whatever it needs to do while the thread eventually shuts down.

要解决它,也许您可​​以创建一个打开流的工作线程,等待100个字节,然后关闭。与此同时,当线程最终关闭时,您的程序可以执行任何需要执行的操作。

#2


0  

So, I finally figured this out a couple of weeks back and verified it with Microsoft as well. The difference between C# and Java is the fact that in Java close call closes the request/connection as well, while in C#, it doesn't happen unless you follow it up with an xxxRequest.Abort() call. Hope this helps someone else as well.

所以,我终于在几个星期后想出了这一点,并与微软进行了验证。 C#和Java之间的区别在于,Java close调用也会关闭请求/连接,而在C#中,除非您使用xxxRequest.Abort()调用,否则它不会发生。希望这也有助于其他人。

#1


3  

I'm assuming sockets of some kind here. I would suspect that the Java implementation is simply closing the client socket, possibly causing an error on the server, whilst the C# version is being slightly more friendly to the server and waiting for it to acknowledge a close request. Since the server is busy firing off data, it doesn't get - or at least doesn't process - the close request until it's finished sending.

我在这里假设某种插座。我怀疑Java实现只是关闭客户端套接字,可能导致服务器上的错误,而C#版本对服务器稍微友好并等待它确认关闭请求。由于服务器忙于触发数据,因此在完成发送之前,它不会 - 或者至少不会处理 - 关闭请求。

Think of it this way: somebody at your front door trying to sell you something and won't be interrupted. You can slam the door in their face which shuts them up immediately, or you can wait until they've finished talking and then ask them to leave.

可以这样想:你前门的某个人试图卖给你一些东西而且不会被打断。你可以将门砰地一声关上,然后立即关闭它们,或者你可以等到他们说完话然后让他们离开。

To solve it, perhaps you could create a worker thread that opens the stream, waits for the 100 bytes, then closes. In the meantime your program can do whatever it needs to do while the thread eventually shuts down.

要解决它,也许您可​​以创建一个打开流的工作线程,等待100个字节,然后关闭。与此同时,当线程最终关闭时,您的程序可以执行任何需要执行的操作。

#2


0  

So, I finally figured this out a couple of weeks back and verified it with Microsoft as well. The difference between C# and Java is the fact that in Java close call closes the request/connection as well, while in C#, it doesn't happen unless you follow it up with an xxxRequest.Abort() call. Hope this helps someone else as well.

所以,我终于在几个星期后想出了这一点,并与微软进行了验证。 C#和Java之间的区别在于,Java close调用也会关闭请求/连接,而在C#中,除非您使用xxxRequest.Abort()调用,否则它不会发生。希望这也有助于其他人。