NamedPipeClientStream.Write 块
Posted
技术标签:
【中文标题】NamedPipeClientStream.Write 块【英文标题】:NamedPipeClientStream.Write blocks 【发布时间】:2021-03-23 14:51:05 【问题描述】:我只是想了解 C# 中的管道。我有一个简单的 LinqPad 脚本:
void Main() => Program.Main(null);
// You can define other methods, fields, classes and namespaces here
class Program
public static void Main(string[] args)
StartServer();
Task.Delay(1000).Wait();
//Client
var client = new NamedPipeClientStream("PipesOfPiece");
client.Connect();
while (true)
string input = Guid.NewGuid().ToString();
if (String.IsNullOrEmpty(input)) break;
var someBuffer = new byte[4];
client.Write(someBuffer, 0, someBuffer.Length);
"Client 1st Write".Dump();
client.Write(someBuffer, 0, someBuffer.Length);
"Client 2nd Write".Dump();
client.Read(someBuffer, 0, someBuffer.Length);
"Client 1st Read".Dump();
static void StartServer()
Task.Factory.StartNew(() =>
var server = new NamedPipeServerStream("PipesOfPiece");
server.WaitForConnection();
var someBuffer = new byte[4];
while (true)
server.Read(someBuffer, 0, someBuffer.Length);
"Server 1st Read".Dump();
server.Write(someBuffer, 0, someBuffer.Length);
"Server 1st Write".Dump();
);
如果我运行上面的代码,我会得到以下输出:
Client 1st Write
Server 1st Read
所以对client.Write
的第二次调用将永远阻塞。有人可以解释一下为什么第二次调用 write(在同一个线程中)会导致管道永远阻塞吗?
谢谢
【问题讨论】:
什么是Dump()
?
Stream.Write
是同步方法,即阻塞。如果您想避免阻塞,请使用WriteAsync
。您必须将签名更改为static async Task Main
。
【参考方案1】:
其根本原因是根据synchrozniation context 和线程切换阻塞问题。 像这个家伙那样做:
public static async Task Main(string[] args)
StartServer();
await Task.Delay(1000);
//Client
var client = new NamedPipeClientStream("PipesOfPiece");
await client.ConnectAsync();
while (true)
string input = Guid.NewGuid().ToString();
if (String.IsNullOrEmpty(input)) break;
var someBuffer = new byte[4];
await client.WriteAsync(someBuffer, 0, someBuffer.Length);
Console.WriteLine("Client 1st Write");
await client.WriteAsync(someBuffer, 0, someBuffer.Length);
Console.WriteLine("Client 2nd Write");
await client.ReadAsync(someBuffer, 0, someBuffer.Length);
Console.WriteLine("Client 1st Read");
//await Task.Delay(100);
static void StartServer()
Task.Factory.StartNew(async () =>
var server = new NamedPipeServerStream("PipesOfPiece");
await server.WaitForConnectionAsync();
var someBuffer = new byte[4];
while (true)
await server.ReadAsync(someBuffer, 0, someBuffer.Length);
Console.WriteLine("Server 1st Read");
await server.WriteAsync(someBuffer, 0, someBuffer.Length);
Console.WriteLine("Server 1st Write");
);
【讨论】:
我得到了一些与同步一样的输出。例如Client 1st Write Server 1st Read
。所以第二个WriteAsync
似乎陷入了僵局。
亲爱的 Moerwald 很遗憾我听不懂你在说什么,请澄清你的话以上是关于NamedPipeClientStream.Write 块的主要内容,如果未能解决你的问题,请参考以下文章