- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我实现了一个模拟串行端口的 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/
这个小项目背后的想法是开发一个不同的聊天应用程序,我想发送对象而不是纯字符串。到目前为止,这就是我所拥有的。 如果我在构造函数上反序列化,它工作得很好(UserDTO 目前只有 2 个字符串字段),但
我正在尝试写一个 TcpClient执行。我想在处理数据时开始下一次读取,但我不确定何时将字节数组传递给 BeginRead被修改。这是我当前的实现 private void ProcessData(
我无法找到在成功的 HttpWebRequest 后取消/终止异步读取操作的方法。无法设置超时,ThreadPool.RegisterWaitForSingleObject 也不起作用。并且关闭底层套
关于这篇文章: http://msdn.microsoft.com/en-us/library/system.net.security.sslstream.beginread.aspx 是否有关于如何
我需要从我的虚拟 com 端口读取数据并检测消息“Dreq”。一旦我按下连接按钮,它就会连接到我的 COM8 端口并开始读取新线程。我还有一个断开连接按钮,我希望在其中关闭读数并断开与 COM8 端口
我正在用 TcpClient 编码一个服务器/客户端项目和 NetworkStream对象。我希望许多客户端连接到服务器,这些客户端存储在 List<> 中定制NetworkNode对象,每个对象都有
我正在编写一个类,该类公开流的一部分以供阅读。由于可能同时从多个不同的子部分读取数据,因此在任何时候只能进行一个操作。 我想到了在每次操作之前锁定底层流。在 BeginRead 调用周围锁定流是否足以
我正在运行一个有 5000 个 UdpClient 实例的应用程序类,因为我需要在不同的端口上同时传输数据包。 我目前正在使用 System.Timers.Timer ,它在 ThreadPool 上
有一个异步服务器的代码。 Client 发送 Header - Data Block + Data Block 的大小。 服务器首先异步读取Header,然后读取Data Block。 我需要在读取数
好的,我想连接到 Socket 并使用 System.Net.Sockets.NetworkStream 类读取网络流。这是我目前所拥有的: NetworkStream myNetworkStream
使用 .NET TcpClient 如果我在关联的网络流上调用了异步 BeginRead(),我仍然可以调用 Write()在另一个线程的那个流上? 或者我是否必须 lock() 从 BeginRea
假设我有一个流链,执行压缩 -> 加密 -> 文件 I/O。 在 C# 中,使用同步 I/O,它看起来像这样: int n=0; byte[] buffer= new byte[2048];
运行这段代码时: private async void StartChat(Object obj) { TcpClient me = (TcpClient)obj; UpdateCha
当使用异步代码通过 BeginXXX/EndXXX 模式从流等中读取时,我相信在调用 EndXXX 时会抛出在此过程中发生的任何异常。 这是否意味着对 BeginXXX 的初始调用永远不会抛出异常,它
我有一个用 C# 编写的实用程序,用于与我们的 USB 设备来回通信。我们使用通用 HID 驱动程序并将设备句柄包装在 FileStream 对象中。我使用它的 BeginRead 和 BeginWr
我还不太“了解”async 和 await,我正在寻找关于我将要解决的特定问题的一些说明。基本上,我需要编写一些代码来处理 TCP 连接。它基本上只是接收数据并处理它,直到连接关闭。 我通常使用 Ne
它在 MSDN documentation 中声明那: at the very minimum, your state parameter must contain the connected or
为什么使用 FileOptions.Asynchronous 创建 FileStream 会导致 FileStream.BeginRead 阻塞调用线程? 这是代码片段: private static
我创建了 ReadByteContainer 来存储当前数据,并创建了 ReadByteAsyncCallback 用于回调。是否有更好的替代方案? HRESULT MediaByte
我实现了一个模拟串行端口的 DataReceived 事件的系统,通过使用 BeginRead() 方法触发从 TCPClient 对象的 NetworkStream 读取数据,如下所示: TcpCl
我是一名优秀的程序员,十分优秀!