Asycnch file reading ?

S

Sunit Joshi

All
I'm trying to use the asynchronous method of reading a big file and
outputting it but somehow it prints out the whole file before running
the main routine.

Here's the code.

using System;
using System.IO;
using System.Threading;
using System.Text;

class AsynchFile
{
private FileStream fs;
private byte[] buffer;
const int bufSize = 256;
private AsyncCallback myCallback;

AsynchFile()
{
buffer = new byte[bufSize];
fs = new FileStream("mis_solidSymbols.log", FileMode.Open,
FileAccess.Read);
myCallback = new AsyncCallback(this.OnCompletedRead);
}

void Run()
{
fs.BeginRead(buffer, 0, buffer.Length, myCallback, null);
//Do some work while data is read
for(int i=0; i<500000; i++)
{
if(i%1000==0)
{
Console.WriteLine("** i ** : {0}", i);
//Thread.Sleep(10);
}
}
fs.Close();
}
void OnCompletedRead(IAsyncResult asyncResult)
{
int bytesRead = fs.EndRead(asyncResult);
//If we got bytes, display them and start again. Otherwise we are
done
if(bytesRead>0)
{
string s = Encoding.ASCII.GetString(buffer,0,bytesRead);
Console.WriteLine(s);
fs.BeginRead(buffer, 0, buffer.Length, myCallback, null);
}
}
public static void Main()
{
AsynchFile theApp = new AsynchFile();
theApp.Run();
}
}

It prints this line Console.WriteLine("** i ** : {0}", i); at the end.

thanks
Sunit
 
N

Nicholas Paldino [.NET/C# MVP]

Sunit,

The problem here is that your program is ending before anything can be
done. You are calling Run, which kicks off the asynchronous read
immediately. However, this occurs on another thread, so the thread that
made the call is free to continue. At that point, it exits. You have to
make it so that your main thread waits until the read is done. In order to
do this, you might want to create an event that the main thread waits on.
Then again, the implementation of IAsyncResult returned by BeginRead will do
this, and you can wait until that WaitHandle is set.

Hope this helps.
 
S

Sunit Joshi

Found the problem...looks like I have to specify Asynchronous mode in
the constructor. If I replaced the FileStream constructor with this

fs = new FileStream("mis_solidSymbols.log", FileMode.Open,
FileAccess.Read,
FileShare.None, bufSize, true);

it seemed to work fine...first some index count, then some filedata,
again count, again file data and finally end of count.

thanks
Sunit

Nicholas Paldino said:
Sunit,

The problem here is that your program is ending before anything can be
done. You are calling Run, which kicks off the asynchronous read
immediately. However, this occurs on another thread, so the thread that
made the call is free to continue. At that point, it exits. You have to
make it so that your main thread waits until the read is done. In order to
do this, you might want to create an event that the main thread waits on.
Then again, the implementation of IAsyncResult returned by BeginRead will do
this, and you can wait until that WaitHandle is set.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Sunit Joshi said:
All
I'm trying to use the asynchronous method of reading a big file and
outputting it but somehow it prints out the whole file before running
the main routine.

Here's the code.

using System;
using System.IO;
using System.Threading;
using System.Text;

class AsynchFile
{
private FileStream fs;
private byte[] buffer;
const int bufSize = 256;
private AsyncCallback myCallback;

AsynchFile()
{
buffer = new byte[bufSize];
fs = new FileStream("mis_solidSymbols.log", FileMode.Open,
FileAccess.Read);
myCallback = new AsyncCallback(this.OnCompletedRead);
}

void Run()
{
fs.BeginRead(buffer, 0, buffer.Length, myCallback, null);
//Do some work while data is read
for(int i=0; i<500000; i++)
{
if(i%1000==0)
{
Console.WriteLine("** i ** : {0}", i);
//Thread.Sleep(10);
}
} fs.Close();
}
void OnCompletedRead(IAsyncResult asyncResult)
{
int bytesRead = fs.EndRead(asyncResult);
//If we got bytes, display them and start again. Otherwise we are
done
if(bytesRead>0)
{
string s = Encoding.ASCII.GetString(buffer,0,bytesRead);
Console.WriteLine(s);
fs.BeginRead(buffer, 0, buffer.Length, myCallback, null);
}
}
public static void Main()
{
AsynchFile theApp = new AsynchFile();
theApp.Run();
}
}

It prints this line Console.WriteLine("** i ** : {0}", i); at the end.

thanks
Sunit
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top