【发布时间】:2018-03-17 19:06:36
【问题描述】:
我为 C# 编写了一个 FastCGI 库。这是在异步/等待之前。现在我正在编写这个库的第 2 版,并考虑到性能。因此,我通过使用 socket.ReceiveAsync 来使用 IOCP。 (注:ReceiveAsync与await/async无关,我要使用ReceiveAsync。)
但是,库的用户可以通过不指定 Content-Length-header 来回答传入的请求。这会导致库需要收集所有传出流量,直到所有数据可用或用户指定 Content-Length。
我的这个库的旧版本通过一个自写的类LocalPipe 实现了这一点。 LocalPipe 只是一个 Stream,您可以在其中写入数据,然后从中读取数据。如果没有足够的可用数据,读取方法将被阻塞。
当LocalPipe 阻塞时,调用线程也在阻塞,因此在等待新数据时不会被释放。这导致了“一个连接/一个线程”的设计,至少在等待来自LocalPipe 的数据时是这样。
我的问题是:是否已经有一个类(作为 NuGet 包或在 .NET 框架本身中)实现了类似于我的 LocalPipe 类但会“阻塞”而不保持调用线程处于使用状态?
我不在寻找await 的常规Task-Pattern,除非它真的可以避免使用不必要的Threads/Tasks 和上下文切换.目前,实现此类“线程消耗友好”的唯一方法似乎是大量使用ExecutionContext 和/或SynchronizationContext,同时我自己实现了一个等待模式。要是能躲开就好了。
【问题讨论】:
-
你试过
BlockingCollection对应的泛型类型吗?或者,也许,MemoryStream? -
两者都不是我正在寻找的。
BlockingCollection是Collection而MemoryStream不是async并且在到达流末尾时不会阻塞。但是,我通过实现自己的管道解决了“问题”。我保持这个问题开放,也许有人知道一个开放的图书馆。编辑:就在有人提到这一点之前:我知道 *Async-methods 来自流。 但是根据参考来源,MemoryStream只是通过在内部直接调用(例如)Read使这些async调用阻塞。
标签: c# .net stream async-await pipe