gpt4 book ai didi

c# - 在 C# 中调用 BeginRead() 后关闭 NetworkStream

转载 作者:太空狗 更新时间:2023-10-29 23:47:56 24 4
gpt4 key购买 nike

我实现了一个模拟串行端口的 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() 方法尚未被调用这一事实有关。如果是这种情况,我如何才能在不崩溃的情况下关闭流?

最佳答案

我会只调用一次 GetStream 并将结果存储在某处并使用它来访问流。

Stream nstrm = server.GetStream();

NetworkStream 的所有访问使用 nstrm...

最安全的方法是维护一个用于关闭的标志,并在 disconnect() 中设置该标志。

DataReceived 中,您将在 EndRead 之后直接检查该标志,如果已设置,请执行以下操作:

server.Close();
nstrm.Close();

参见 http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.getstream.aspx

编辑 - 根据评论:

if (flag2Close)
{
server.Close();
nstrm.Close();
flag2Close = false;
}
else
{
nstrm.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(DataReceived), buffer);
}

顺便说一句:对于生产代码,它需要一些异常处理等。

关于c# - 在 C# 中调用 BeginRead() 后关闭 NetworkStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7094003/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com