.net - 为什么从管道读取会阻塞进程?
问题描述
我有两个进程(两个.NET Framework
应用程序),我正在尝试使用Named Pipes
客户端连接到管道进行通信,但是当它尝试ReadAsync
接收服务器发送的消息时,它开始等待 indifinetly ,即使服务器已经发送了一条消息!
令我惊讶的是,如果我关闭Server
应用程序,Client
最终会继续到下一行代码(在该ReadAsync
行之后),读取0个字节。
WriteAsync
加载有效负载后,我必须在服务器上做些什么吗?我需要冲洗什么的吗?
服务器
static async Task Main(string[] args) {
var server = new NamedPipeServerStream(
"somePipe",
PipeDirection.InOut,
2,
PipeTransmissionMode.Message
);
await server.WaitForConnectionAsync();
using (StreamReader reader = new StreamReader(server)) {
using (StreamWriter writer = new StreamWriter(server)) {
await writer.WriteAsync("Hello from server");
char[] buffer = new char[20];
var read = await reader.ReadAsync(buffer, 0, buffer.Length);
}
}
}
客户
static async Task Main() {
NamedPipeClientStream client = new NamedPipeClientStream(
".",
"somePipe",
PipeDirection.InOut,
PipeOptions.Asynchronous);
await client.ConnectAsync();
try {
using (StreamReader reader = new StreamReader(client)) {
using (StreamWriter writer = new StreamWriter(client)) {
var buffer = new char[20];
int readChars = await reader.ReadAsync(buffer, 0,buffer.Length); //starts waiting indifinetly , until i close the Server
await writer.WriteAsync("From Client");
}
}
} catch (Exception ex) {
throw;
}
}
更新
似乎使用NamedPipeServerStream
直接写入而不是StreamWriter
服务器端使客户端获取数据!
服务器更改
byte[] data=Encoding.UTF8.GetBytes("Hello from server");
server.WriteAsync(data,0,data.Length);
PS
但是再次使用server
来ReadAsync
阻塞服务器。因此将 and 包装到 and时NamedPipeServerStream
会出现问题。ClientStream
StreamReader
StreamWriter
解决方案
此阻塞/锁定问题是由 async/await 语法糖暗中生成的代码引起的。如果不添加ConfigureAwait(false)
,编译器会生成一些对 UI 应用程序来说很酷的东西(UI 是一个通用术语,可能是 ASP.NET - 不是核心 - 、WPF、Winforms 等),但否则可能是致命的。
关于这个问题已经写了很多:
引:
有两种最佳做法 [...] 可以避免这种情况:
- 在您的“库”异步方法中,尽可能使用 ConfigureAwait(false)。
- 不要阻塞任务;一直使用异步。
并行计算 - 一切都与 SynchronizationContext 有关
为所有服务器端代码调用 ConfigureAwait 的最佳实践
我应该在每个等待的操作上调用 ConfigureAwait(false)
因此,最简单的解决方案是在您的代码中添加不知道在 UI 中运行的任何地方,或者在任何地方使用ConfigureAwait(false)
(async
永远不要在整个代码中阻塞任何任务,真的在任何地方,包括在您不拥有的代码中)。
恕我直言,这太荒谬了……如果我忘记在每次async
通话后添加它,我个人会使用一个对我大喊大叫的 Visual Studio 扩展:-)
请注意,有一些替代方法,例如: ConfigureAwait(false) 的替代方法无处不在
推荐阅读
- python - 对数据框 pandas 中的选定数据进行分组
- android - 3 android中的editText & textWatcher问题
- c# - C#中无法识别来自Jsonstream的音素
- php - 无法在 Laravel 迁移中创建外键
- windows - 将 JAVA_HOME 等环境变量放在 .bashrc 或 .profile 或 .bash_login 中的最佳实践是什么?
- c# - 使用 BackgroundWorker 时如何将 e.Result 值返回给 VB6 调用者?
- python - Odoo 从控制台上传和读取文件/读取文件
- azure - cURL 发送 cookie
- python - 如何将一个数据框的列值搜索到另一个数据框
- javascript - 如何为我的应用编写代码以访问设备中的联系人?