Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I cooked up some code that is probably along the lines of the gate idea of Marc.</p> <pre><code>public class PullStream : Stream { private byte[] internalBuffer; private bool ended; private static ManualResetEvent dataAvailable = new ManualResetEvent(false); private static ManualResetEvent dataEmpty = new ManualResetEvent(true); public override bool CanRead { get { return true; } } public override bool CanSeek { get { return false; } } public override bool CanWrite { get { return true; } } public override void Flush() { throw new NotImplementedException(); } public override long Length { get { throw new NotImplementedException(); } } public override long Position { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } public override int Read(byte[] buffer, int offset, int count) { dataAvailable.WaitOne(); if ( count &gt;= internalBuffer.Length) { var retVal = internalBuffer.Length; Array.Copy(internalBuffer, buffer, retVal); internalBuffer = null; dataAvailable.Reset(); dataEmpty.Set(); return retVal; } else { Array.Copy(internalBuffer, buffer, count); internalBuffer = internalBuffer.Skip(count).ToArray(); // i know return count; } } public override long Seek(long offset, SeekOrigin origin) { throw new NotImplementedException(); } public override void SetLength(long value) { throw new NotImplementedException(); } public override void Write(byte[] buffer, int offset, int count) { dataEmpty.WaitOne(); dataEmpty.Reset(); internalBuffer = new byte[count]; Array.Copy(buffer, internalBuffer, count); Debug.WriteLine("Writing some data"); dataAvailable.Set(); } public void End() { dataEmpty.WaitOne(); dataEmpty.Reset(); internalBuffer = new byte[0]; Debug.WriteLine("Ending writes"); dataAvailable.Set(); } } </code></pre> <p>This is a simple stream descendant class only implementing Read and Write (and End). The Read blocks while no data is available and the Write blocks while data is available. This way there is only one byte buffer involved. The linq copying of the rest is open for optimization ;-) The End method is added so no blocking occurs where Read is performed when no data is available and no data will be written any more.</p> <p>You have to write to this stream from a separate thread. I show this below:</p> <pre><code> // create a large object var obj = new List&lt;ToSerialize&gt;(); for(int i = 0; i &lt;= 1000; i ++) obj.Add(new ToSerialize { Test = "This is my very loooong message" }); // create my special stream to read from var ms = new PullStream(); new Thread(x =&gt; { ProtoBuf.Serializer.Serialize(ms, obj); ms.End(); }).Start(); var buffer = new byte[100]; // stream to write back to (just to show deserialization is working too) var ws = new MemoryStream(); int read; while ((read = ms.Read(buffer, 0, 100)) != 0) { ws.Write(buffer, 0, read); Debug.WriteLine("read some data"); } ws.Position = 0; var back = ProtoBuf.Serializer.Deserialize&lt;List&lt;ToSerialize&gt;&gt;(ws); </code></pre> <p>I hope this solves your problem :-) It was fun to code this anyway.</p> <p>Regards, Jacco</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload