/// <summary> /// Releases a <see cref="SocketAwaitable"/> instance back into the pool, so that it can be reused. /// </summary> /// <param name="socketAwaitable">A <see cref="SocketAwaitable"/> to release back into the pool.</param> public void Release(SocketAwaitable socketAwaitable) { Log.Debug(m => m("Releasing socketAwaitable: {0} [{1}, {2}]", socketAwaitable.GetHashCode(), _count, _pool.Count)); _pool.Enqueue(socketAwaitable); _autoResetEvent.Set(); }
/// <summary> /// Begins an asynchronous request to receive data from a connected <see cref="Socket"/> object using await. /// </summary> /// <param name="awaitable">The <see cref="SocketAwaitable"/> to await on.</param> /// <returns>A <see cref="SocketAwaitable"/> object ready to be reused.</returns> public static SocketAwaitable ReceiveAsync(this SocketAwaitable awaitable) { awaitable.Reset(); var socket = awaitable.EventArgs.AcceptSocket; if (!socket.ReceiveAsync(awaitable.EventArgs)) { awaitable.IsCompleted = true; } return(awaitable); }
/// <summary> /// Executes an asynchronous operation. /// </summary> public async Task <IOperationResult <T> > ExecuteAsync <T>(IOperation <T> operation, IConnection connection) { var eventArgs = new SocketAsyncEventArgs { AcceptSocket = connection.Socket, UserToken = new OperationAsyncState { Connection = connection } }; var socketAwaitable = new SocketAwaitable(eventArgs); var buffer = operation.GetBuffer(); socketAwaitable.EventArgs.SetBuffer(buffer, 0, buffer.Length); await socketAwaitable.SendAsync(); await Receive(operation, socketAwaitable); return(operation.GetResult()); }
/// <summary> /// Recieves data from the remote server. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="operation"></param> /// <param name="socketAwaitable"></param> /// <returns></returns> private async Task Receive <T>(IOperation <T> operation, SocketAwaitable socketAwaitable) { var eventArgs = socketAwaitable.EventArgs; var state = (OperationAsyncState)eventArgs.UserToken; socketAwaitable.EventArgs.SetBuffer(state.Buffer, 0, state.Buffer.Length); do { await socketAwaitable.ReceiveAsync(); state.BytesReceived += eventArgs.BytesTransferred; state.Data.Write(eventArgs.Buffer, eventArgs.Offset, eventArgs.Count); Log.Debug(m => m("receive...{0} bytes", state.BytesReceived)); if (operation.Header.BodyLength == 0) { CreateHeader(operation, state); } }while (state.BytesReceived < operation.Header.TotalLength); CreateBody(operation, state); state.Reset(); }
/// <summary> /// Resets a buffer on a <see cref="SocketAwaitable"/> instance. /// </summary> /// <param name="socketAwaitable"></param> /// <remarks>May be obsolete</remarks> public void ResetBuffer(SocketAwaitable socketAwaitable) { _bufferAllocator.ReleaseBuffer(socketAwaitable.EventArgs); _bufferAllocator.SetBuffer(socketAwaitable.EventArgs); }