I have a list of float
to write to a file. The code below does the thing but it is synchronous.
List<float> samples = GetSamples();
using (FileStream stream = File.OpenWrite("somefile.bin"))
using (BinaryWriter binaryWriter = new BinaryWriter(stream, Encoding.Default, true))
{
foreach (var sample in samples)
{
binaryWriter.Write(sample);
}
}
I want to do the operation asynchronously but the BinaryWriter
does not support async operations, which is normal since it just only writes a few bytes each time. But most of the time the operation uses file I/O and I think it can and should be asynchronous.
I tried to write to a MemoryStream
with the BinaryWriter
and when that finished I copied the MemoryStream
to the FileStream
with CopyToAsync
, however this caused a performance degradation (total time) up to 100% with big files.
How can I convert the whole operation to asynchronous?
Normal write operations usually end up being completed asynchronously anyway. The OS accepts writes immediately into the write cache, and flushes it to disk at some later time. Your application isn't blocked by the actual disk writes.
Of course, if you are writing to a removable drive then write cache is typically disabled and your program will be blocked.
I will recommend that you can dramatically reduce the number of operations by transferring a large block at a time. To wit:
new T[BlockSize]
of your desired block size.new byte[BlockSize * sizeof (T)]
List<T>.CopyTo(index, buffer, 0, buffer.Length)
to copy a batch out of the list.Buffer.BlockCopy
to get the data into the byte[]
.byte[]
to your stream in a single operation.