public virtual IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
{
if (!CanRead) __Error.ReadNotSupported();
// Increment the count to account for this async operation
BCLDebug.Assert(_asyncActiveCount >= 1, "ref counting mismatch, possible race in the code");
Interlocked.Increment(ref _asyncActiveCount);
ReadDelegate d = new ReadDelegate(Read);
// To avoid a race with a stream's position pointer & generating race
// conditions with internal buffer indexes in our own streams that
// don't natively support async IO operations when there are multiple
// async requests outstanding, we will block the application's main
// thread if it does a second IO request until the first one completes.
if (_asyncActiveEvent == null) {
lock(this) {
if (_asyncActiveEvent == null)
_asyncActiveEvent = new AutoResetEvent(true);
}
}
bool r = _asyncActiveEvent.WaitOne();
BCLDebug.Assert(r, "AutoResetEvent didn't get a signal when we called WaitOne!");
BCLDebug.Assert(_readDelegate == null && _writeDelegate == null, "Expected no other readers or writers!");
// Set delegate before we call BeginInvoke, to avoid a race
_readDelegate = d;
IAsyncResult asyncResult = d.BeginInvoke(buffer, offset, count, callback, state);
return asyncResult;
}