我已经实现了一个模拟串行端口的DataReceived事件的系统,其中从TCPClient对象的NetworkStream读取数据是使用BeginRead()方法触发的,如下所示:
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我还尝试实现disconnect方法,如下所示:
server.GetStream().Close();但这会导致以下错误:
A first chance exception of type 'System.InvalidOperationException' occurred in System.dll我认为这与调用了BeginRead()方法而没有调用EndRead()方法有关。如果是这种情况,我如何才能在不崩溃的情况下关闭流?
发布于 2011-08-17 22:08:09
我只会调用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);
}顺便说一句:对于产品代码,它需要一些异常处理等。
https://stackoverflow.com/questions/7094003
复制相似问题