C# TcpClient/NetworkStream在同一实例上同时读写
我需要与只接受1个TCP连接的硬件进行通信。但是我找不到任何好的例子,在那里相同的C# TcpClient/NetworkStream在同一实例上同时读写,c#,.net-core,tcpclient,C#,.net Core,Tcpclient,我需要与只接受1个TCP连接的硬件进行通信。但是我找不到任何好的例子,在那里相同的NetworkStream被同时用于读写 报告说: 读和写操作可以在一台计算机上同时执行 NetworkStream类的实例,而不需要 同步。只要有一个用于写入的唯一线程 操作和一个用于读取操作的唯一线程 读写线程之间没有交叉干扰,也没有 需要同步 但是,我找不到一个示例来说明如何在不同的线程中使用NetworkStream的相同实例进行读写 我不确定是否应该: 只需直接使用NetworkStream与myNet
NetworkStream
被同时用于读写
报告说:
读和写操作可以在一台计算机上同时执行
NetworkStream类的实例,而不需要
同步。只要有一个用于写入的唯一线程
操作和一个用于读取操作的唯一线程
读写线程之间没有交叉干扰,也没有
需要同步
但是,我找不到一个示例来说明如何在不同的线程中使用NetworkStream
的相同实例进行读写
我不确定是否应该:
- 只需直接使用
与NetworkStream
一起读取,或使用myNetworkStream.ReadAsync()
StreamReader
- 只需直接使用
使用NetworkStream
进行写入,或使用myNetworkStream.WriteAsync()
StreamWriter
- 直接用
启动一个新线程,以便在实例化while(true)
时读取TcpClient
- 保留对我的
实例的全局引用,以便我可以随时编写NetworkStream
提前感谢:)记住,对于I/O绑定的任务 您发布的段落并不真正涉及任务,例如:
var client = new TcpClient();
await client.ConnectAsync("example.com", 80);
var stream = client.GetStream();
// start reading from the socket
var rBuf = new byte[2048];
var tRecv = stream.ReadAsync(rBuf, 0, rBuf.Length);
// send data and wait for it to complete
var sBuf = Encoding.UTF8.GetBytes("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n");
await stream.WriteAsync(sBuf, 0, sBuf.Length);
// now await for the data
var bytesRecv = await tRecv;
Console.WriteLine($"Received {bytesRecv} bytes");
在处理底层流时,没有两个线程同时执行某些操作
这一段所说的是这样做的:
var client = new TcpClient();
await client.ConnectAsync("example.com", 80);
var stream = client.GetStream();
new Thread(() =>
{
var rBuf = new byte[2048];
var bytesRecv = stream.Read(rBuf, 0, rBuf.Length);
Console.WriteLine($"Received {bytesRecv} bytes");
}).Start();
Thread.Sleep(500); // ensure the above thread has started
new Thread(() =>
{
var sBuf = Encoding.UTF8.GetBytes("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n");
stream.Write(sBuf, 0, sBuf.Length);
}).Start();
Console.ReadKey(true);
在上面的示例中,您有两个不同的线程,它们都在使用底层流同时执行某些操作,并且没有任何“爆炸”
至于你应该用什么样的图案。。。你有一些可能性。上面有第一个关于任务的示例(现代方法),或者可以使用阻塞调用执行线程while(true)
方法(“老式”方法)。或者开始…
和结束…
方法(在旧式和现代之间)
什么是最好的?你选择。就个人而言,我喜欢在数据可用时触发事件,因此我倾向于使用BeginConnect
/EndConnect
,BeginReceive
/EndReceive
等方法
但有时,我喜欢使用ReadAsync()
执行while(true)
,但使用CancellationToken
终止循环
我不建议对阻塞调用使用
while(true)
。有了TPL提供的出色工具,我们不必再启动通用线程来完成任何事情。我会使用管道模式,
看看代码和中的文章,这些都是您可以选择或不选择做的事情。这不是一种真正的“一种正确的方法”的情况。你能举个例子说明如何使用同一个NetworStream同时读写吗?听起来不错,我完全赞成不使用线程,但是,我需要与之通信的硬件可能会连续发送数据,我如何确保我有某种类型的线程“进程”,它在接收数据时不断接收和引发事件,同时仍然能够时不时地向它发送一些东西,所有这些都不需要在不同的线程中使用while(true)阻塞?@Seb-您可以启动一个
任务
,该任务位于while(true){ReceiveAsync()}
并在数据准备就绪时触发事件。或者使用BeginReceive
方法,这基本上是做同样的事情。一个任务需要一段时间(真的)?不是相反?一个任务需要一段时间(真的)?非常有趣,谢谢!