示例#1
0
        /// <summary>Rents a <see cref="Int32TaskSocketAsyncEventArgs"/> for immediate use.</summary>
        /// <param name="isReceive">true if this instance will be used for a receive; false if for sends.</param>
        private Int32TaskSocketAsyncEventArgs RentSocketAsyncEventArgs(bool isReceive)
        {
            // Get any cached SocketAsyncEventArg we may have.
            CachedTaskEventArgs           cea  = LazyInitializer.EnsureInitialized(ref _cachedTaskEventArgs);
            Int32TaskSocketAsyncEventArgs saea = isReceive ?
                                                 Interlocked.Exchange(ref cea.Receive, s_rentedInt32Sentinel) :
                                                 Interlocked.Exchange(ref cea.Send, s_rentedInt32Sentinel);

            if (saea == s_rentedInt32Sentinel)
            {
                // An instance was once created (or is currently being created elsewhere), but some other
                // concurrent operation is using it. Since we can store at most one, and since an individual
                // APM operation is less expensive than creating a new SAEA and using it only once, we simply
                // return null, for a caller to fall back to using an APM implementation.
                return(null);
            }

            if (saea == null)
            {
                // No instance has been created yet, so create one.
                saea            = new Int32TaskSocketAsyncEventArgs();
                saea.Completed += isReceive ? ReceiveCompletedHandler : SendCompletedHandler;
            }

            return(saea);
        }
示例#2
0
        /// <summary>Dispose of any cached <see cref="Int32TaskSocketAsyncEventArgs"/> instances.</summary>
        private void DisposeCachedTaskSocketAsyncEventArgs()
        {
            CachedTaskEventArgs cea = _cachedTaskEventArgs;

            if (cea != null)
            {
                Interlocked.Exchange(ref cea.Accept, s_rentedSocketSentinel)?.Dispose();
                Interlocked.Exchange(ref cea.Receive, s_rentedInt32Sentinel)?.Dispose();
                Interlocked.Exchange(ref cea.Send, s_rentedInt32Sentinel)?.Dispose();
            }
        }