I was playing with asynchronous file I/O and I noticed a weird behavior.
It seems to be tagged on a buffer size being constant.
The code below reads a file and copies the contents to another file.
Search for line that looks like this
iSize += 08;//Make this increment…
If you let the iSize be constant the runtime behavior changes a lot.
I was thinking that some “buggy” optimization code tries to reuse the data buffer (for same size scenario) and this causes the problem…
using System.IO;
using System.Threading;
...
class AsynchFileProcess
{
private const int BUFF_SIZE = 256;
private long writeCount = 0;
private long readCount = 0;
private FileStream istrm;
private FileStream ostrm;
private String outFileName;
public void ProcessFile(String fileName)
{
istrm = new FileStream(fileName, FileMode.Open,
FileAccess.Read, FileShare.Read,
BUFF_SIZE, true);
FileInfo fi = new FileInfo(fileName);
String dir = fi.Directory.ToString();
do
{
outFileName = dir + "/" + Guid.NewGuid().ToString();
fi = new FileInfo(outFileName);
} while (fi.Exists);
ostrm = new FileStream(outFileName, FileMode.CreateNew,
FileAccess.Write, FileShare.None,
BUFF_SIZE, true);
long Length = istrm.Length;
int iSize = BUFF_SIZE;
while (Length != istrm.Position)
{
iSize += 08;//Make this increment 0 and the executable will hang and run sloooow
byte[] data = new Byte[iSize];
istrm.BeginRead(data, 0, data.Length, new AsyncCallback(onReadBuffer), data);
Interlocked.Increment(ref readCount);
}
//wait for all the read operations to complete
while (0 != Interlocked.CompareExchange(ref readCount, 0, 0))
Thread.Sleep(250);
istrm.Close();
//wait for all the write operations to complete
while (0 != Interlocked.CompareExchange(ref writeCount, 0, 0))
Thread.Sleep(250);
ostrm.Close();
}
private void onReadBuffer(IAsyncResult result)
{
Byte[] data = (Byte[])result.AsyncState;
int bytesRead = istrm.EndRead(result);
Interlocked.Increment(ref writeCount);
ostrm.BeginWrite(data, 0, bytesRead, new AsyncCallback(onWriteBuffer), null);
Interlocked.Decrement(ref readCount);
Console.WriteLine("bytesRead={0} buffersCnt={1} thread={2}", bytesRead, readCount, Thread.CurrentThread.GetHashCode());
}
private void onWriteBuffer(IAsyncResult result)
{
ostrm.EndWrite(result);
Interlocked.Decrement(ref writeCount);
Console.WriteLine("writeCnt={0} thread={1}", writeCount, Thread.CurrentThread.GetHashCode());
}
}