Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# TcpClient/NetworkStream在同一实例上同时读写_C#_.net Core_Tcpclient - Fatal编程技术网

C# TcpClient/NetworkStream在同一实例上同时读写

C# TcpClient/NetworkStream在同一实例上同时读写,c#,.net-core,tcpclient,C#,.net Core,Tcpclient,我需要与只接受1个TCP连接的硬件进行通信。但是我找不到任何好的例子,在那里相同的NetworkStream被同时用于读写 报告说: 读和写操作可以在一台计算机上同时执行 NetworkStream类的实例,而不需要 同步。只要有一个用于写入的唯一线程 操作和一个用于读取操作的唯一线程 读写线程之间没有交叉干扰,也没有 需要同步 但是,我找不到一个示例来说明如何在不同的线程中使用NetworkStream的相同实例进行读写 我不确定是否应该: 只需直接使用NetworkStream与myNet

我需要与只接受1个TCP连接的硬件进行通信。但是我找不到任何好的例子,在那里相同的
NetworkStream
被同时用于读写

报告说:

读和写操作可以在一台计算机上同时执行 NetworkStream类的实例,而不需要 同步。只要有一个用于写入的唯一线程 操作和一个用于读取操作的唯一线程 读写线程之间没有交叉干扰,也没有 需要同步

但是,我找不到一个示例来说明如何在不同的线程中使用
NetworkStream
的相同实例进行读写

我不确定是否应该:

  • 只需直接使用
    NetworkStream
    myNetworkStream.ReadAsync()
    一起读取,或使用
    StreamReader
  • 只需直接使用
    NetworkStream
    使用
    myNetworkStream.WriteAsync()
    进行写入,或使用
    StreamWriter
  • 直接用
    while(true)
    启动一个新线程,以便在实例化
    TcpClient
    时读取
  • 保留对我的
    NetworkStream
    实例的全局引用,以便我可以随时编写
在TCP连接/网络通信方面,我远不是一个专家,所以肯定有一些事情我不完全理解


提前感谢:)

记住,对于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
方法,这基本上是做同样的事情。一个任务需要一段时间(真的)?不是相反?一个任务需要一段时间(真的)?非常有趣,谢谢!