在 C# 中调用 BeginRead() 后关闭 NetworkStream
我已经实现了一个模仿串行端口的 DataReceived 事件的系统,通过使用 BeginRead() 方法触发从 TCPClient 对象的 NetworkStream 读取数据,如下所示:
TcpClient server = new TcpClient();
server.Connect(IPAddress.Parse(ip), 10001);
server.GetStream().BeginRead(buffer, 0, buffer.Length, new AsyncCallback(DataReceived), server.GetStream());
该方法从另一个线程调用以下方法:
private void DataReceived(IAsyncResult result)
{
res = result;
server.GetStream().EndRead(result);
//append received data to the string buffer
stringBuffer += System.Text.ASCIIEncoding.ASCII.GetString(buffer);
//clear the byte array
Array.Clear(buffer, 0, buffer.Length);
//trigger the parser
waitHandle.Set();
server.GetStream().BeginRead(buffer, 0, buffer.Length, new AsyncCallback(DataReceived), buffer);
}
这似乎有效正确。我可以毫无问题地向网络上的设备发送和接收数据。但是,当我尝试使用以下方法断开连接时,程序崩溃:
public override void disconnect()
{
server.Close();
}
它抛出以下错误:
A first chance exception of type 'System.ObjectDisposedException' occurred in System.dll
我还尝试按如下方式实现断开连接方法:
server.GetStream().Close();
但这会导致以下错误:
A first chance exception of type 'System.InvalidOperationException' occurred in System.dll
我认为这与事实上,BeginRead() 方法已被调用,而 EndRead() 方法尚未调用。如果是这种情况,我怎样才能关闭流而不崩溃?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我只会调用一次 GetStream 并将结果存储在某处并使用它来访问流。
对
NetworkStream
的所有访问都使用nstrm
...最安全的方法是维护一个用于关闭的标志,然后在
disconnect()
中设置该标志.在
DataReceived
中,您可以在EndRead
之后直接检查该标志,如果已设置,请执行以下操作:请参阅 http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.getstream.aspx
编辑 - 根据评论:
顺便说一句:用于生产代码需要一些异常处理等。
I would call
GetStream
just once and store the result somewhere and use that for accessing the stream.Use
nstrm
for all accesses to theNetworkStream
...safest way would be to maintain a flag for closing down and just setting that flag in
disconnect()
.In
DataReceived
you would directly afterEndRead
check for that flag and if it is set do this:see http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.getstream.aspx
EDIT - as per comment:
BTW: for production code it needs some exception handling etc.