我希望在Windows匿名管道上进行非阻塞io。这是一个.NET项目,所以我计划尽可能使用托管类。我看到.NET确实有一个AnonymousPipeServerStream和一个AnonymousPipeClientStream。我看到BeginRead()/ BeginWrite()和ReadAsync()/ WriteAsync()方法。但是来自:
它说:
“匿名管道不支持异步(重叠)读取和写入操作。这意味着您不能将ReadFileEx和WriteFileEx函数与匿名管道一起使用。此外,当这些函数是以下时,将忽略ReadFile和WriteFile的lpOverlapped参数。与匿名管道一起使用。“
所以我想知道托管异步方法是如何工作的?它们是作为在io工作线程上运行的同步方法实现的吗?如果是这样,如果我最终阻止几个io工作线程,那不会有问题吗?
谢谢, 尼克
答案 0 :(得分:3)
首先,ReadAsync()
/ WriteAsync()
的默认实现只需使用TaskFactory<Int32>.FromAsync
的修剪版本调用BeginRead()
/ BeginWrite()
方法, PipeStream
也不会AnonymousPipeServerStream
覆盖它,因此我们只需知道BeginRead()
/ BeginWrite()
的工作原理。
在AnonymousPipeServerStream
it calls
InitializeHandle(serverSafePipeHandle, true, false);
InitializeHandle
的最后一个参数是isAsync
,如果它为假calling BeginRead()
则会调用
return base.BeginRead(buffer, offset, count, callback, state);
BeginRead(
的基本实现创建了一个新主题和calls the synchronous _stream.Read(
method。
所以问题的答案是他们如何让异步工作&#34;他们不会,他们只是通过在另一个线程上调用同步方法来伪造它。&#34; < / em>的
P.S。:如果你做File.Open("SomeFile")
,它会做同样的事情。您必须使用FileStream
并明确传入FileOptions.Asynchronous
以获取Begin方法和Async方法,以便通过生成新线程来执行请求来伪造它。
答案 1 :(得分:0)
正如https://stackoverflow.com/a/51448441/14237276中所指出的 Anonymous 实际上是建立在 Named 之上的。这意味着可以通过 NamedPipe 函数更改句柄上的属性,或者如果您只是想在不阻塞的情况下读取, PeekNamedPipe 可在读取前仅获取 TotalBytesAvail。