none
Use BinaryWriter asynchronously?

Answers

  • BinaryWriter doesn't provide BeginWrite() overloads.  You could let BinaryWriter write into a MemoryStream, that will be really fast, then write the MemoryStream buffer into a FileStream with BeginWrite().
    Thursday, July 19, 2007 4:34 PM

All replies

  • BinaryWriter doesn't provide BeginWrite() overloads.  You could let BinaryWriter write into a MemoryStream, that will be really fast, then write the MemoryStream buffer into a FileStream with BeginWrite().
    Thursday, July 19, 2007 4:34 PM
  • I see, thank you very much.

    Thursday, July 19, 2007 6:12 PM
  • Dear nobugz,

    I did my BinaryWriter class. It looks like this.

        public class AsyncBinaryWriter : BinaryWriter

        {

            public AsyncBinaryWriter(Stream output, Encoding encoding)

                : base(new MemoryStream(), encoding)

            {

                this.outStream = output;

                this.memory = (MemoryStream) base.BaseStream;

                this.callback = new AsyncCallback(WriteFinished);

            }

            …. There’ are many overrides here.  All like following one.

            public override void Write(string value)

            {

                base.Write(value);

                CheckForFlushInternal();

            }

            public override void Flush()

            {

                if (this.memory != null)

                {

                    byte[] buffer = this.memory.ToArray();

     

                    this.memory.SetLength(0);

     

        this.outStream.BeginWrite(buffer, 0, buffer.Length, this.callback, null);

                }

            }

      public override void Close() { … }

      protected override void Dispose(bool disposing) { … }

            const int bufferCapacity = 2048;

            private AsyncCallback callback;

     

            private MemoryStream memory;

     

            private Stream outStream;

     

            private void CheckForFlushInternal()

            {

                if (this.memory.Position > bufferCapacity)

                {

                    Flush();

                }

            }

     

            private void WriteFinished(IAsyncResult ar)

            {

                this.outStream.EndWrite(ar);

            }

    }

    It’s done and works well.

    Now I need to make asynchronous my BinaryReader.

    What should I do?

    Friday, July 20, 2007 3:13 PM
  • That's the long way to do it.  You just need to override the BaseStream property so BinaryWriter is writing into a MemoryStream.  Here's an example:

    using System;
    using System.IO;

    public class AsyncBinaryWriter : BinaryWriter {
      private Stream mOutput;
      private MemoryStream mBuffer;
      private int mOutputIndex;
      public AsyncBinaryWriter(Stream output) {
        mOutput = output;
        mBuffer = new MemoryStream();
      }
      public override Stream BaseStream {
        get { return mBuffer; }
      }
      public override void Flush() {
        mOutput.Flush();
        mOutputIndex = (int)mBuffer.Length;
      }
      public override void Close() {
        mOutput.Close();
      }
      public IAsyncResult BeginWrite(AsyncCallback callback, object state) {
        IAsyncResult retval = mOutput.BeginWrite(mBuffer.GetBuffer(), mOutputIndex, (int)mBuffer.Length - mOutputIndex, callback, state);
        mOutputIndex = (int)mBuffer.Length;
        return retval;
      }
      public void EndWrite(IAsyncResult result) {
        mOutput.EndWrite(result);
      }
    }

    Note that I haven't tested this.  Mixing up synchronous and asynchronous writing can be tricky.  Hope it works for you.
    Friday, July 20, 2007 4:01 PM
  • I have written the class in this way for a reason.

    The code above the writer doesn’t care what writer it uses.

     

    See the example

     

    #if USE_ASYNC_WRITER

    using(BinaryWriter wr = new AsyncBinaryWriter(fileStream))

    //Now we have asynchronous write in output stream

    #else

    using(BinaryWriter wr = new BinaryWriter(fileStream))

    //Now we have System.IO.BinaryWriter used

    #endif

    {

                wr.Write(“This is a test”);

                wr.Write(123);

    }


    Now I’m wandering how to write the reader.

    It appears it’s not as easy as the writer.

    Saturday, July 21, 2007 5:51 AM
  • Oh.  Just beware that writing chars and strings is highly non-trivial.  You can't just call Base.BeginWrite().  You can't make Read() asynchronous without the client's participation.
    Saturday, July 21, 2007 6:19 AM