Hello. was thinking why the named pipe api doesn't provide the possibility to use array segments as the socket api to be able to use buffer pooling to reduce the impact of pinning for arrays that are not big enough to make it to LOH. is a common technique with socket to avoid possible out of memory exception due to fragmentation. I am having nightmares because a new app we are building is doing a lot of io via named pipes and now OOM exceptions are all over the place. Any plan about this kind of features?
@KrzysztofCwalina, seems related to System.Buffers.
Related but not quite the same.
@colombod we currently do not have a specific feature in mind for this. This is a fairly complex area and I suspect it will be a lot of work/thinking to get this right.
Is this something you are interested in prototyping and seeing what a surface area / implementation / challenges would look like?
Could give it a try!
Awesome! :)
Let us know how we can help out! :)
Will get some proposal across, the idea is to mirror the signature of the api for async IO on socket using segments, the idea is to reduce the need for contiguous buffers at least when reading, as you point out will need quite few thinking on it.
@KrzysztofCwalina, @stephentoub I presume this would be answered by Span
I presume this would be answered by Span APIs?
I'm unclear on the suggestion. @colombod, can you clarify? I'm unclear how ArraySegment<byte> APIs would actually enable something that's not possible today; you can certainly pool buffers and pass them into Read/Write/ReadAsync/WriteAsync methods. ArraySegment<byte> is just a struct that wraps the byte[] with the offset and count ints, and if you have an ArraySegment<byte>, you can just pass its Array, Offset, and Count into the corresponding arguments. If the request is purely to be able to have other Read/Write/ReadAsync/WriteAsync overloads that work with some kind of "segment"-like type that encompasses a byte[] along with an offset and a count, then yeah, that should be covered by the new {ReadOnly}Memory<byte> and {ReadOnly}Span<byte>-based overloads already added to Stream for 2.1.
Array segment is good and can be used on the socket api, but is not generally available on other io apis like on named pipes for example. The new span and memory api seem to hit the spot! They totally map the problem space I was hitting with the conventional stream api
is not generally available on other io apis like on named pipes for example
Not built in, but you can easily add them yourself via extensions, e.g.
```C#
public static int Read(this Stream s, ArraySegment
s.Read(buffer.Array, buffer.Offset, buffer.Count);
public static void Write(this Stream s, ArraySegment
s.Write(buffer.Array, buffer.Offset, buffer.Count);
```
The only thing I was doing on top of spans was to see them as a memory buffer and then be able to represent a required X amount of memory as a set of spans. The extension is interesting but the interesting part would be to be able to pass the Memory object all the way down to native call instead of keep on doing pinvoke for each span. Time to deep-dive in the span and memory api, looks gorgeous
Ok, thanks. Sounds like this can be closed then.
Most helpful comment
I'm unclear on the suggestion. @colombod, can you clarify? I'm unclear how
ArraySegment<byte>APIs would actually enable something that's not possible today; you can certainly pool buffers and pass them into Read/Write/ReadAsync/WriteAsync methods.ArraySegment<byte>is just a struct that wraps thebyte[]with the offset and count ints, and if you have anArraySegment<byte>, you can just pass its Array, Offset, and Count into the corresponding arguments. If the request is purely to be able to have other Read/Write/ReadAsync/WriteAsync overloads that work with some kind of "segment"-like type that encompasses abyte[]along with an offset and a count, then yeah, that should be covered by the new{ReadOnly}Memory<byte>and{ReadOnly}Span<byte>-based overloads already added to Stream for 2.1.