private void ProcessSend()
{
// Return if we are closing the socket
if (SocketClosed) return;
// Bool holder
bool willRaiseEvent = true;
// Prevent an connection loss exception
try
{
// Prevent race conditions by locking here.
// ** Make sure to set WaitingOnAsync Inside the LOCK! **
lock (_lockObj)
{
// If we are waiting on the IO operation to complete, we exit here
if (WaitingOnAsync) return;
// Get the number of bytes remaining to be sent
int NumBytesToSend = SendMessage.Count - SendBytesOffset;
// If there are no more bytes to send, then reset
if (NumBytesToSend <= 0)
{
SendMessage.Clear();
SendBytesOffset = 0;
WaitingOnAsync = false;
return;
}
// Make sure we arent sending more data then what we have space for
BufferDataToken Token = WriteEventArgs.UserToken as BufferDataToken;
if (NumBytesToSend > Token.BufferBlockSize)
NumBytesToSend = Token.BufferBlockSize;
// Copy our message to the Write Buffer
SendMessage.CopyTo(SendBytesOffset, WriteEventArgs.Buffer, Token.BufferOffset, NumBytesToSend);
WriteEventArgs.SetBuffer(Token.BufferOffset, NumBytesToSend);
// We have to exit the lock() before we can handle the event manually
WaitingOnAsync = true;
willRaiseEvent = Connection.SendAsync(WriteEventArgs);
}
}
catch (ObjectDisposedException)
{
WaitingOnAsync = false;
Close();
}
// If we wont raise the IO event, that means a connection sent the messsage syncronously
if (!willRaiseEvent)
{
// Remember, if we are here, data was sent Synchronously... IOComplete event is not called!
// First, Check for a closed conenction
if (WriteEventArgs.BytesTransferred == 0 || WriteEventArgs.SocketError != SocketError.Success)
{
Close();
return;
}
// Append to the offset
SendBytesOffset += WriteEventArgs.BytesTransferred;
WaitingOnAsync = false;
ProcessSend();
}
}