public void TestGettingAwaiter() { var awaitable = new SocketAwaitable(); var awaiter = awaitable.GetAwaiter(); Assert.IsTrue(awaiter.IsCompleted); Assert.AreEqual(awaiter.GetResult(), default(SocketError)); }
public void TestInitialization() { // Default values. var awaitable = new SocketAwaitable(); Assert.IsNull(awaitable.AcceptSocket); var awaiter = awaitable.GetAwaiter(); Assert.IsTrue(awaiter.IsCompleted); Assert.AreEqual(awaiter.GetResult(), SocketError.Success); }
public async Task TestAwaiterStatus() { using (var listener = new Socket(SocketType.Stream, ProtocolType.Tcp)) { listener.Bind(new IPEndPoint(IPAddress.IPv6Any, 0)); listener.Listen(1); var acceptTask = Task.Run(async() => { using (var awaitable = new SocketAwaitable()) { var awaiter = awaitable.GetAwaiter(); Assert.IsTrue(awaiter.IsCompleted); Assert.AreEqual(awaiter.GetResult(), SocketError.Success); var a = listener.AcceptAsync(awaitable); Assert.IsFalse(awaiter.IsCompleted); Assert.AreEqual(awaiter.GetResult(), SocketError.AlreadyInProgress); var result = await a; Assert.IsTrue(awaiter.IsCompleted); Assert.AreEqual(awaiter.GetResult(), result); } }); await Task.Delay(500); using (var client = new Socket(SocketType.Stream, ProtocolType.Tcp)) { using (var awaitable = new SocketAwaitable()) { awaitable.RemoteEndPoint = new IPEndPoint( IPAddress.IPv6Loopback, (listener.LocalEndPoint as IPEndPoint).Port); var awaiter = awaitable.GetAwaiter(); Assert.IsTrue(awaiter.IsCompleted); Assert.AreEqual(awaiter.GetResult(), SocketError.Success); var a = client.ConnectAsync(awaitable); Assert.IsFalse(awaiter.IsCompleted); Assert.AreEqual(awaiter.GetResult(), SocketError.AlreadyInProgress); var result = await a; Assert.IsTrue(awaiter.IsCompleted); Assert.AreEqual(awaiter.GetResult(), result); } } await acceptTask; } }
/// <summary> /// Calls the specified asynchronous method of a <see cref="Socket" /> and returns an awaitable /// object that provides the operation result when awaited. /// </summary> /// <param name="socket"> /// <see cref="Socket" /> to run an asynchronous operation. /// </param> /// <param name="awaitable"> /// The <see cref="SocketAwaitable" /> object to use for this asynchronous socket operation. /// </param> /// <param name="operation"> /// Socket operation to perform. /// </param> /// <returns> /// A <see cref="SocketAwaitable" /> which, when awaited, returns a <see cref="SocketError" /> /// object that corresponds to the result of <paramref name="operation" />. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="socket" /> or <paramref name="awaitable" /> is null. /// </exception> /// <exception cref="InvalidOperationException"> /// A socket operation was already in progress using <paramref name="awaitable"/>. /// -or- /// For accept operations: /// <paramref name="socket" /> is not bound, is not listening for connections, or is already connected. /// -or- /// For connect operations: /// <paramref name="socket" /> is listening. /// </exception> /// <exception cref="NotSupportedException"> /// Windows XP or later is required for this method. /// -or- /// For connect operations: /// Address family of <see cref="Socket.LocalEndPoint" /> is different than the address family of /// <see cref="SocketAsyncEventArgs.RemoteEndPoint" />. /// </exception> /// <exception cref="ObjectDisposedException"> /// <paramref name="socket" /> has been disposed. /// </exception> /// <exception cref="SecurityException"> /// For connection operations: /// A caller higher in the call stack does not have permission for the requested operation. /// </exception> private static SocketAwaitable OperateAsync( Socket socket, SocketAwaitable awaitable, Func<Socket, SocketAwaitable, bool> operation) { if (socket == null) throw new ArgumentNullException("socket", "Socket must not be null."); if (awaitable == null) throw new ArgumentNullException("awaitable", "Awaitable must not be null."); var a = awaitable.GetAwaiter(); lock (a.SyncRoot) { if (!a.IsCompleted) throw new InvalidOperationException( "A socket operation is already in progress using the same awaitable arguments."); a.Reset(); if (awaitable.ShouldCaptureContext) a.SyncContext = SynchronizationContext.Current; } try { if (!operation.Invoke(socket, awaitable)) a.Complete(); } catch (SocketException x) { a.Complete(); awaitable.Arguments.SocketError = x.SocketErrorCode != SocketError.Success ? x.SocketErrorCode : SocketError.SocketError; } catch (Exception) { a.Complete(); awaitable.Arguments.SocketError = SocketError.Success; throw; } return awaitable; }