private void ReadComplete(IAsyncResult transportResult)
{
while(true)
{
// Recover our asyncResult
InnerAsyncResult userResult = transportResult.AsyncState as InnerAsyncResult;
try
{
if (!userResult.IsWriteCompletion)
{
userResult.Count = m_OriginalStream.EndRead(transportResult);
if (userResult.Count == 0)
m_SeenReadEOF = true;
if (!m_ShadowStreamIsDead) {
userResult.IsWriteCompletion = true;
//Optionally charge notification write IO
transportResult = m_ShadowStream.BeginWrite(userResult.Buffer, userResult.Offset, userResult.Count, m_ReadCallback, userResult);
if (transportResult.CompletedSynchronously)
{
continue;
}
return;
}
}
else
{
GlobalLog.Assert(!m_ShadowStreamIsDead, "ForwardingReadStream::ReadComplete|ERROR: IsWriteCompletion && m_ShadowStreamIsDead");
m_ShadowStream.EndWrite(transportResult);
userResult.IsWriteCompletion = false;
}
}
catch (Exception e)
{
//ASYNC: try to swallow even serious exceptions (nothing to loose?)
if (userResult.InternalPeekCompleted)
{
GlobalLog.Print("ShadowReadStream::ReadComplete() Rethrowing Exception (end), userResult.IsCompleted, stack trace = " + e.ToString());
throw;
}
try
{
m_ShadowStreamIsDead = true;
if (m_ShadowStream is ICloseEx)
((ICloseEx)m_ShadowStream).CloseEx(CloseExState.Abort | CloseExState.Silent);
else
m_ShadowStream.Close();
}
catch (Exception ee)
{
//ASYNC: Again try to swallow even serious exceptions
GlobalLog.Print("ShadowReadStream::ReadComplete() Got (ignoring) Exception, on shadow stream.Close, stack trace = " + ee.ToString());
}
catch
{
//ASYNC: Again try to swallow even serious exceptions
GlobalLog.Print("ShadowReadStream::ReadComplete() Got (ignoring) Exception, on shadow stream.Close, stack trace = Non-CLS Compliant Exception");
}
if (!userResult.IsWriteCompletion || m_ThrowOnWriteError)
{
if (transportResult.CompletedSynchronously)
{
throw;
}
userResult.InvokeCallback(e);
return;
}
}
catch {
//ASYNC: try to swallow even serious exceptions (nothing to loose?)
if (userResult.InternalPeekCompleted)
{
GlobalLog.Print("ShadowReadStream::ReadComplete() Rethrowing Exception (end), userResult.IsCompleted, stack trace = Non-CLS Compliant Exception");
throw;
}
try
{
m_ShadowStreamIsDead = true;
if (m_ShadowStream is ICloseEx)
((ICloseEx)m_ShadowStream).CloseEx(CloseExState.Abort | CloseExState.Silent);
else
m_ShadowStream.Close();
}
catch (Exception ee)
{
//ASYNC: Again try to swallow even serious exceptions
GlobalLog.Print("ShadowReadStream::ReadComplete() Got (ignoring) Exception, on shadow stream.Close, stack trace = " + ee.ToString());
}
catch
{
//ASYNC: Again try to swallow even serious exceptions
GlobalLog.Print("ShadowReadStream::ReadComplete() Got (ignoring) Exception, on shadow stream.Close, stack trace = Non-CLS Compliant Exception");
}
if (!userResult.IsWriteCompletion || m_ThrowOnWriteError)
{
if (transportResult.CompletedSynchronously)
{
throw;
}
userResult.InvokeCallback(new Exception(SR.GetString(SR.net_nonClsCompliantException)));
return;
}
}
// Need to process, re-issue the read.
try
{
if (m_BytesToSkip != 0L) {
m_BytesToSkip -= userResult.Count;
userResult.Count = m_BytesToSkip < (long)userResult.Buffer.Length? (int)m_BytesToSkip: userResult.Buffer.Length;
if (m_BytesToSkip == 0L) {
// we did hide the original IO request in the outer iaresult state.
// charge the real user operation now
transportResult = userResult;
userResult = userResult.AsyncState as InnerAsyncResult;
GlobalLog.Assert(userResult != null, "ForwardingReadStream::ReadComplete|ERROR: Inner IAResult is null after stream FastForwarding.");
}
transportResult = m_OriginalStream.BeginRead(userResult.Buffer, userResult.Offset, userResult.Count, m_ReadCallback, userResult);
if (transportResult.CompletedSynchronously)
{
continue;
}
return;
}
//if came to here, complete original user IO
userResult.InvokeCallback(userResult.Count);
return;
}
catch (Exception e)
{
//ASYNC: try to swallow even serious exceptions (nothing to loose?)
if (userResult.InternalPeekCompleted)
{
GlobalLog.Print("ShadowReadStream::ReadComplete() Rethrowing Exception (begin), userResult.IsCompleted, stack trace = " + e.ToString());
throw;
}
try
{
m_ShadowStreamIsDead = true;
if (m_ShadowStream is ICloseEx)
((ICloseEx)m_ShadowStream).CloseEx(CloseExState.Abort | CloseExState.Silent);
else
m_ShadowStream.Close();
}
catch (Exception ee)
{
//ASYNC: Again try to swallow even serious exceptions
GlobalLog.Print("ShadowReadStream::ReadComplete() Got (ignoring) Exception, on shadow stream.Close (after begin), stack trace = " + ee.ToString());
}
catch
{
//ASYNC: Again try to swallow even serious exceptions
GlobalLog.Print("ShadowReadStream::ReadComplete() Got (ignoring) Exception, on shadow stream.Close (after begin), stack trace = Non-CLS Compliant Exception");
}
if (transportResult.CompletedSynchronously)
{
throw;
}
// This will set the exception result first then try to execute a user callback
userResult.InvokeCallback(e);
return;
}
catch
{
//ASYNC: try to swallow even serious exceptions (nothing to loose?)
if (userResult.InternalPeekCompleted)
{
GlobalLog.Print("ShadowReadStream::ReadComplete() Rethrowing Exception (begin), userResult.IsCompleted, stack trace = Non-CLS Compliant Exception");
throw;
}
try
{
m_ShadowStreamIsDead = true;
if (m_ShadowStream is ICloseEx)
((ICloseEx)m_ShadowStream).CloseEx(CloseExState.Abort | CloseExState.Silent);
else
m_ShadowStream.Close();
}
catch (Exception ee)
{
//ASYNC: Again try to swallow even serious exceptions
GlobalLog.Print("ShadowReadStream::ReadComplete() Got (ignoring) Exception, on shadow stream.Close (after begin), stack trace = " + ee.ToString());
}
catch
{
//ASYNC: Again try to swallow even serious exceptions
GlobalLog.Print("ShadowReadStream::ReadComplete() Got (ignoring) Exception, on shadow stream.Close (after begin), stack trace = Non-CLS Compliant Exception");
}
if (transportResult.CompletedSynchronously)
{
throw;
}
// This will set the exception result first then try to execute a user callback
userResult.InvokeCallback(new Exception(SR.GetString(SR.net_nonClsCompliantException)));
return;
}
}
}