//private static void ReconfigLazyInstance() //{ // _instance = new Lazy<SocketAsyncEventArgsPool>( // PoolFactory, // false); //} public static SocketAsyncEventArgsPool GetInstance() { //lock (_criticalLock) //{ // return _instance.Value; //} if (_instance == null) { lock (_criticalLock) { if (_instance == null) { _instance = PoolFactory(); } } } return(_instance); }
//private static void ReconfigLazyInstance() //{ // _instance = new Lazy<SocketAsyncEventArgsPool>( // PoolFactory, // false); //} public static SocketAsyncEventArgsPool GetInstance() { //lock (_criticalLock) //{ // return _instance.Value; //} if (_instance == null) { lock (_criticalLock) { if (_instance == null) { _instance = PoolFactory(); } } } return _instance; }
private static SocketAsyncEventArgsPool PoolFactory() { //Create buffer blocks. //long acturalBufferSize = (long)_poolSize * (long)_bufferSize; //var steps = acturalBufferSize / _bufferBlockStepSize; //var mod = acturalBufferSize % _bufferBlockStepSize; //if (mod > 0) //{ // steps++; //} //int maxBufferBlockSize = _maxBuffersInBufferBlockCount * _bufferSize; //long totalSize = (long)(steps * _bufferBlockStepSize); //var fullBlockCount = (int)(totalSize / maxBufferBlockSize); //var lastBlockSize = totalSize % maxBufferBlockSize; //var buffers = // Enumerable.Range(0, fullBlockCount) // .Select( // i => new byte[maxBufferBlockSize] // ) // .ToList(); //if (lastBlockSize != 0) buffers.Add(new byte[(int)lastBlockSize]); //Create reserved items in overlap pool. //These overlap objects in SAES will be return to overlap pool for other io after SAE pool is built. var reservedList = Enumerable.Range(0, _reservedOverlapCount) .Select( i => { unsafe { NativeOverlapped* ptr = new Overlapped().Pack((x, y, z) => { }, null); return new Action(() => { Overlapped.Free(ptr); }); } } ) .ToList(); //Create working SAEs var query = Enumerable.Range(0, _poolSize) .Select ( i => { var e = new SocketAsyncEventArgs(); //long totalOffset = i * (long)_bufferSize; //var blockIndex = (int)(totalOffset / maxBufferBlockSize); //var offset = (int)(totalOffset % maxBufferBlockSize); e.SetBuffer(new byte[_bufferSize], 0, _bufferSize); return e; } ); var itmsList = query.ToList(); //Create SAE pool instance var rval = new SocketAsyncEventArgsPool(new ConcurrentBag<SocketAsyncEventArgs>(itmsList)); //Release the reserved overlap object. //Best practice of overlap pool: the last released object will be visited first. reservedList.Reverse(); reservedList.ForEach( act => { try { act(); } catch (Exception) { } } ); reservedList.Clear(); //make sure all items in pool are in MaxGen of GC for (int i = 0; i < GC.MaxGeneration; i++) { GC.Collect(); GC.WaitForFullGCComplete(); } //Pin all buffer & SocketEventArgs to GC. //GC will ignore them. return rval; }
private static SocketAsyncEventArgsPool PoolFactory() { //Create buffer blocks. //long acturalBufferSize = (long)_poolSize * (long)_bufferSize; //var steps = acturalBufferSize / _bufferBlockStepSize; //var mod = acturalBufferSize % _bufferBlockStepSize; //if (mod > 0) //{ // steps++; //} //int maxBufferBlockSize = _maxBuffersInBufferBlockCount * _bufferSize; //long totalSize = (long)(steps * _bufferBlockStepSize); //var fullBlockCount = (int)(totalSize / maxBufferBlockSize); //var lastBlockSize = totalSize % maxBufferBlockSize; //var buffers = // Enumerable.Range(0, fullBlockCount) // .Select( // i => new byte[maxBufferBlockSize] // ) // .ToList(); //if (lastBlockSize != 0) buffers.Add(new byte[(int)lastBlockSize]); //Create reserved items in overlap pool. //These overlap objects in SAES will be return to overlap pool for other io after SAE pool is built. var reservedList = Enumerable.Range(0, _reservedOverlapCount) .Select( i => { unsafe { NativeOverlapped *ptr = new Overlapped().Pack((x, y, z) => { }, null); return(new Action(() => { Overlapped.Free(ptr); })); } } ) .ToList(); //Create working SAEs var query = Enumerable.Range(0, _poolSize) .Select ( i => { var e = new SocketAsyncEventArgs(); //long totalOffset = i * (long)_bufferSize; //var blockIndex = (int)(totalOffset / maxBufferBlockSize); //var offset = (int)(totalOffset % maxBufferBlockSize); e.SetBuffer(new byte[_bufferSize], 0, _bufferSize); return(e); } ); var itmsList = query.ToList(); //Create SAE pool instance var rval = new SocketAsyncEventArgsPool(new ConcurrentBag <SocketAsyncEventArgs>(itmsList)); //Release the reserved overlap object. //Best practice of overlap pool: the last released object will be visited first. reservedList.Reverse(); reservedList.ForEach( act => { try { act(); } catch (Exception) { } } ); reservedList.Clear(); //make sure all items in pool are in MaxGen of GC for (int i = 0; i < GC.MaxGeneration; i++) { GC.Collect(); GC.WaitForFullGCComplete(); } //Pin all buffer & SocketEventArgs to GC. //GC will ignore them. return(rval); }