iso*_*rik 5 c# asynchronous 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());
Run Code Online (Sandbox Code Playgroud)
从另一个线程调用以下方法:
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);
}
Run Code Online (Sandbox Code Playgroud)
这似乎工作正常.我可以毫无问题地向网络上的设备发送和接收数据.但是,当我尝试使用以下方法断开连接时,程序崩溃:
public override void disconnect()
{
server.Close();
}
Run Code Online (Sandbox Code Playgroud)
它会引发以下错误:
A first chance exception of type 'System.ObjectDisposedException' occurred in System.dll
Run Code Online (Sandbox Code Playgroud)
我也尝试过如下实现disconnect方法:
server.GetStream().Close();
Run Code Online (Sandbox Code Playgroud)
但这会导致以下错误:
A first chance exception of type 'System.InvalidOperationException' occurred in System.dll
Run Code Online (Sandbox Code Playgroud)
我假设这与调用BeginRead()方法并且EndRead()方法没有调用这一事实有关.如果是这种情况,我怎么能关闭流而不会崩溃?
我只会调用GetStream一次并将结果存储在某处并使用它来访问流。
Stream nstrm = server.GetStream();
Run Code Online (Sandbox Code Playgroud)
用于nstrm对NetworkStream...的所有访问
最安全的方法是维护一个用于关闭的标志,然后将该标志设置为disconnect().
在检查该标志DataReceived后,您将直接EndRead执行以下操作:
server.Close();
nstrm.Close();
Run Code Online (Sandbox Code Playgroud)
请参阅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);
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句:对于生产代码,它需要一些异常处理等。