3

I'm curious as to whether making changes to the byte[] before BeginWrite actually finishes writing, will influence what is finally written by the FileStream.

I've this code below, with currentPage being a byte[] with the data I want to write.

try
{
FileStream.BeginWrite(currentPage, 0, currentPage.Length, new AsyncCallback(EndWriteCallback),new State(logFile.fs, currentPage, BUFFER_SIZE, manualEvent));
manualEvent.WaitOne();
}
catch (Exception e)
{
  //handle exception here
}

I have this within a loop that will replace the data in currentPage. What will happen if I make changes to currentPage (like assign a new byte[] with all 0's in it)? Does FileStream buffer the byte[] to be written somewhere or does it actually just references the byte[] I passed in when I call it?

I tried looking at the MSDN article but all I could find was

Multiple simultaneous asynchronous requests render the request completion order uncertain.

Could someone please explain this to me?

tshepang
  • 12,111
  • 21
  • 91
  • 136
JasonY
  • 31
  • 5
  • To me an "uncertain completion order" implies that the function's not thread-safe, which probably means that doing anything with the `byte[]` could cause unintended consequences. – Michael Todd Oct 01 '14 at 22:42
  • Yes, the device driver reads directly from *currentPage*. [More here](http://stackoverflow.com/a/7555664/17034). – Hans Passant Oct 01 '14 at 23:39

1 Answers1

1

This code should answer your questions. Firstly I create a long byte array where every cell is equal to 255. Then I start 2 threads. The first one is responsible for writing the prepared byte array to file. At the same time the second thread modifies this array, starting from the last cell, by setting every cell to 0.

The exact results of executing this code will depend on the machine, current CPU usage etc. On my computer one time I observed that about 77% of the created file contained 255s and the rest 0s. The next time it was about 70%. It confirms that the input array is not blocked for writing by BeginWrite method.

In order to observe this effect try to run this program a few times. It might be also necessary to use the longer array.

var path = @"C:\Temp\temp.txt";

var list = new List<byte>();
for(var  i = 0; i < 1000000; ++i)
    list.Add(255);

var buffer = list.ToArray();

var t1 = Task.Factory.StartNew(() =>
{
    using (var fs = File.OpenWrite(path))
    {
        var res = fs.BeginWrite(buffer, 0, buffer.Length, null, null);
        res.AsyncWaitHandle.WaitOne();
    }
 });

var t2 = Task.Factory.StartNew(() =>
{
     for (var i = buffer.Length - 1; i > 0; --i)
         buffer[i] = 0;
});

Task.WaitAll(t1, t2);
Michał Komorowski
  • 6,198
  • 1
  • 20
  • 24