Windows匿名管道上的非阻塞io

本文关键字:io 管道 Windows | 更新日期: 2023-09-27 18:14:49

我希望在Windows匿名管道上做非阻塞io。这是一个。net项目,所以如果可能的话,我计划使用托管类。我看到。net有一个AnonymousPipeServerStream和一个AnonymousPipeClientStream。我看到两个BeginRead()/BeginWrite()和ReadAsync()/WriteAsync()方法。然而从:

匿名管道操作

它说:

"匿名管道不支持异步(重叠)读写操作。这意味着您不能将ReadFileEx和WriteFileEx函数与匿名管道一起使用。此外,ReadFile和WriteFile的lpoverlap参数在与匿名管道一起使用时被忽略。"

所以我想知道托管异步方法是如何工作的?它们是否作为同步方法实现在io工作线程上运行?如果是这样,如果我最终阻塞了几个io工作线程,那不是一个问题吗?

谢谢,尼克

Windows匿名管道上的非阻塞io

首先,ReadAsync()/WriteAsync()的默认实现只是使用TaskFactory<Int32>.FromAsync的修剪版本调用BeginRead()/BeginWrite()方法,PipeStreamAnonymousPipeServerStream都不会覆盖它,所以我们只需要知道BeginRead()/BeginWrite()是如何工作的。

AnonymousPipeServerStream的构造函数中它调用

InitializeHandle(serverSafePipeHandle, true, false);

InitializeHandle的最后一个参数是isAsync,如果它为假,调用BeginRead()将调用

return base.BeginRead(buffer, offset, count, callback, state);

BeginRead(的基本实现创建一个新线程并调用同步的_stream.Read(方法。

所以你的问题的答案是他们是如何让异步工作的是"他们不,他们只是通过在另一个线程上调用同步方法来假装它。"

注:如果你做一个File.Open("SomeFile"),它会做同样的事情。您必须使用FileStream并显式地传递FileOptions.Asynchronous来获得Begin方法和Async方法,以避免通过生成新线程来执行请求。

正如https://stackoverflow.com/a/51448441/14237276所指出的那样Anonymous实际上是建立在Named之上的。这意味着你可以通过NamedPipe函数改变句柄上的属性,或者如果你只是想在没有阻塞的情况下读取,PeekNamedPipe获取TotalBytesAvail