/// <summary> /// Start receiving data from the socket. /// </summary> public void Start() { // don't start if disposing if (_disposing) { return; } // ensure we don't start multiple times if (Interlocked.CompareExchange(ref _started, 1, 0) == 1) { // already started! can't call Start() twice. throw new InvalidOperationException("Cannot call AsyncSocket.Start() more than once."); } // configure for receive var args = SocketEventArgsCache.AllocateForReceive(OnSocketReceive); // start a receive request and immediately check to see if the receive is already complete // otherwise OnIOCompleted will get called when the receive is complete if (!Socket.ReceiveAsync(args)) { ReceiveSocketData(args); } }
/// <summary> /// Complete processing a buffer of bytes read from the socket. /// </summary> private void CompleteReceive() { // ReadSocketData temporarily releases the lock (and then enters it again), so we need to ensure // we haven't disposed in the meantime if (_disposing) { _readLock.Release(); return; } if (_receivedBuffer.TakeItem().Length > 0) { _receivedBuffer.Release(); ManagerUpdate.Control.AddSingle(ProcessReceivedData); return; } _receivedBuffer.Release(); // flop the processing flag _readLock.Release(); // any bytes in the queue? if (_receivedBuffer.TakeItem().Length > 0 && _readLock.TryTake) { _receivedBuffer.Release(); ManagerUpdate.Control.AddSingle(ProcessReceivedData); return; } _receivedBuffer.Release(); // socket may have been closed already due to connection error. // if not try receiving more data if (Socket.Connected) { // receiveAsync returns true if the I/O operation is pending. An event will be raised upon completion. // returns false if the I/O operation completed synchronously. var args = SocketEventArgsCache.AllocateForReceive(OnSocketReceive); if (!Socket.ReceiveAsync(args)) { ReceiveSocketData(args); } } else { if (_disposing) { return; } ProcessError("Cannot receive, socket is not connected."); } }