internal void FireEvent(T value) { var key = (int)value.Type; if (events.ContainsKey(key)) { List <Action <T> > list = events[key]; if (list != null) { for (int i = 0; i < list.Count; ++i) { Action <T> action = list[i]; if (action != null) { action.Invoke(value); } } } } IPoolItem poolItem = value as IPoolItem; if (poolItem != null) { poolItem.Dispose(); } }
public EventSubscriber(string eventName, string group) { _eventName = eventName; _queue = string.Format("{0}-{1}", eventName, group); _isWorking = false; _busItem = RabbitBus.Borrow(Event.Policy); }
/// <summary> /// Releases a item and puts it back in the available stack /// </summary> /// <typeparam name="T">Type of the item to release</typeparam> /// <param name="item">The instance of <typeparamref name="T"/> which should be released</param> /// <exception cref="ArgumentException">Is thrown if the <paramref name="item"/> was not created using <see cref="ObjectPool.Aquire"/></exception> /// <exception cref="ArgumentNullException">Is thrown if <paramref name="item"/> is null</exception> public static void Release(IPoolItem item) { if (item == null) { throw new ArgumentNullException("item"); } if (locked[item.GetType()].Contains(item) == false) { // @TODO: Find out why this is even necessary if (locked[item.GetType()].Count == 0) { locked.Remove(item.GetType()); } //throw new ArgumentException("Release item has not been aquired"); } else { locked[item.GetType()].Remove(item); } item.Release(); free[item.GetType()].Add(item); }
public RPCClient(int millisecondsTimeout) { _busItem = RabbitBus.Borrow(RPC.Policy); InitConsumer(); _signal = new AutoResetEvent(false); _millisecondsTimeout = millisecondsTimeout; }
/** 调用对象方法--销毁 */ virtual protected void ItemDestruct(T instance) { if (IsImplementIPoolItem) { IPoolItem item = (IPoolItem)instance; item.PDestruct(); } }
/** 给实例对象重命名 */ virtual protected void nameInstance(T instance) { if (IsImplementIPoolItem) { IPoolItem item = (IPoolItem)instance; item.PName += (this.totalCount + 1).ToString("#000"); } }
/** 调用对象方法--设置是否激活 */ virtual protected void ItemSetActive(T instance, bool value) { if (IsImplementIPoolItem) { IPoolItem item = (IPoolItem)instance; item.PSetActive(value); } }
/** 调用对象方法--实例对象重设参数 */ virtual protected void ItemSetArg(T instance, params object[] args) { if (IsImplementIPoolItem) { IPoolItem item = (IPoolItem)instance; item.PSetArg(args); } }
/** 调用对象方法--设置为闲置状态消息 */ virtual protected void ItemOnDespawned(T instance) { if (IsImplementIPoolItem) { IPoolItem item = (IPoolItem)instance; item.POnDespawned(this); } }
/** 调用对象方法--设置为使用状态消息 */ virtual internal void ItemOnSpawned(T instance) { if (IsImplementIPoolItem) { IPoolItem item = (IPoolItem)instance; item.POnSpawned(this); } }
public void Return(T item) { IPoolItem <WrapperItem <T> > poolItem = null; if (!_map.TryGetValue(item, out poolItem)) { throw new PoolingException(string.Format(Strings.NotFoundPoolItem, item.ToString())); } _pool.Return(poolItem); }
/// <summary> /// 获取一个值,表示该项是否是损坏的,如果是损坏的,那么应该从它所属的Pool{T}实例中将该项移除 /// </summary> /// <param name="item"></param> /// <returns></returns> public bool GetCorrupted(T item) { IPoolItem <WrapperItem <T> > poolItem = null; if (!_map.TryGetValue(item, out poolItem)) { throw new PoolingException(string.Format(Strings.NotFoundPoolItem, item.ToString())); } return(poolItem.IsCorrupted); }
private bool TryTakeOrCreate(out IPoolItem <T> poolItem) { if (_pool.TryTake(out var item)) { poolItem = _poolItemFactory(item); return(true); } return(TryCreate(out poolItem)); }
public void Push(IPoolItem item) { if (this.item == item) { return; } item.OnPushed(); stack.Push(item.Instance); }
public PoolItem(T instance) { used = false; this.instance = instance; Type itemType = instance.GetType(); if (typeof(IPoolItem).IsAssignableFrom(itemType)) { poolItem = instance as IPoolItem; } }
public void Push(IPoolItem <TTag> poolItem) { if (null == poolItem) { return; } Push(poolItem.poolTag, poolItem); poolItem.inPool = true; poolItem.OnPushPool(); }
/// <summary> /// <para>Sends a <see cref="Stream"/> of containing data serialized from /// <paramref name="dataSerializer"/> and <paramref name="data"/> to /// <see cref="AsyncSocketClient.EndPoint"/> with <paramref name="commandId"/>. /// Calls <paramref name="resultAction"/> when all data has been sent to /// the destination. Please note that this is just a tcp acknowledgement that the data /// was received and not an acknowlegements that the data was processed.</para> /// </summary> /// <typeparam name="T">The type of data to be sent.</typeparam> /// <param name="commandId">The command id.</param> /// <param name="data">The data to send.</param> /// <param name="dataSerializer"> /// <para>A method to serialize <paramref name="data"/> into a <see cref="Stream"/>.</para> /// </param> /// <param name="resultAction"> /// <para>The method that will be called when the remote end point acknowledges that the data was /// recieved, the operation fails, or the operation times out.</para> /// </param> /// <exception cref="ArgumentNullException"> /// <para><paramref name="dataSerializer"/> is <see langword="null"/>.</para> /// <para>- or -</para> /// <para><paramref name="resultAction"/> is <see langword="null"/>.</para> /// </exception> public void SendOneWayAsync <T>( short commandId, T data, Procedure <T, Stream> dataSerializer, Action <OneWayAsyncEventArgs> resultAction) { if (dataSerializer == null) { throw new ArgumentNullException("dataSerializer"); } if (resultAction == null) { throw new ArgumentNullException("resultAction"); } var sendData = _memoryPool.Borrow(); IPoolItem <SocketChannel> socket = null; try { ClientMessage.WriteMessage <T>( sendData.Item, _socketPool.Config.NetworkOrdered, commandId, _messageId, // must never send 0 otherwise the server header coming back will be the wrong size false, data, dataSerializer); sendData.Item.Seek(0, SeekOrigin.Begin); socket = _socketPool.Pool.Borrow(); socket.Item.SendOneWayAsync( _socketPool.Config.ReceiveTimeout, sendData, e => { socket.Dispose(); resultAction(e); }); } catch { if (socket != null) { socket.IsCorrupted = true; socket.Dispose(); } sendData.Dispose(); throw; } }
public void Push(IPoolItem <T> item) { if (_root == null) { Object.Destroy(item.GameObject); } else { item.GameObject.transform.parent = _root; item.ReturnToPool(); _items[item.Key].Push(item); } }
public void Dispose() { IPoolItem <WrapperItem <V> > poolItem = null; _map.TryRemove(_value, out poolItem); var disposable = _value as IDisposable; if (disposable != null) { disposable.Dispose(); } }
public static PoolManager AddPool(IPoolItem item, Transform instancesParent) { if (pools.ContainsKey(item.id)) { return(pools[item.id]); } PoolManager poolManager = new PoolManager(item, instancesParent); pools.Add(item.id, poolManager); return(poolManager); }
/// <summary> /// <para>Creates a new instance of the <see cref="RoundTripAsyncEventArgs"/> class.</para> /// </summary> /// <param name="completedSynchronously"> /// <para><see langword="true"/> if the operation completed synchronously; otherwise, <see langword="false"/>.</para> /// </param> /// <param name="error"> /// <para>Gets the error if there was one; otherwise gets <see langword="null"/>.</para> /// </param> /// <param name="response">The response data.</param> /// <param name="completionAction">The completion action that will be called when <see cref="ICompletion.Complete"/> is called.</param> /// <returns> /// <para>A new instance of the <see cref="RoundTripAsyncEventArgs"/> class.</para> /// </returns> internal static RoundTripAsyncEventArgs Create( bool completedSynchronously, Exception error, IPoolItem <MemoryStream> response, Action <RoundTripAsyncEventArgs> completionAction) { return(new RoundTripAsyncEventArgs { CompletedSynchronously = completedSynchronously, Error = error, _response = response, _completionAction = completionAction }); }
/// <summary> /// <para>Creates a new instance of the <see cref="RoundTripAsyncEventArgs"/> class.</para> /// </summary> /// <param name="completedSynchronously"> /// <para><see langword="true"/> if the operation completed synchronously; otherwise, <see langword="false"/>.</para> /// </param> /// <param name="error"> /// <para>Gets the error if there was one; otherwise gets <see langword="null"/>.</para> /// </param> /// <param name="response">The response data.</param> /// <param name="completionAction">The completion action that will be called when <see cref="ICompletion.Complete"/> is called.</param> /// <returns> /// <para>A new instance of the <see cref="RoundTripAsyncEventArgs"/> class.</para> /// </returns> internal static RoundTripAsyncEventArgs Create( bool completedSynchronously, Exception error, IPoolItem<MemoryStream> response, Action<RoundTripAsyncEventArgs> completionAction) { return new RoundTripAsyncEventArgs { CompletedSynchronously = completedSynchronously, Error = error, _response = response, _completionAction = completionAction }; }
private bool TryCreate(out IPoolItem <T> poolItem) { lock (_sync) { if (_size < _maxSize) { var item = _objectFactory(); ++_size; poolItem = _poolItemFactory(item); return(true); } } poolItem = null; return(false); }
/// <summary> /// Completes the operation. /// </summary> protected internal override void PerformCompletion() { try { if (_completionAction != null) _completionAction(this); } finally { _responseDisposed = true; if (_response != null) { _response.Dispose(); _response = null; } } }
/// <summary> /// 释放一个对象 /// </summary> /// <param name="objHashCode"></param> public void FreeObject(int objHashCode) { if ((bool)_objUseState[objHashCode] == false) { return; } lock (this) { if (_supportReset) { IPoolItem item = (IPoolItem)_listObjects[objHashCode]; item.Reset(); } _listUsingIndex.Remove(objHashCode); _listFreeIndex.Add(objHashCode); _objUseState[objHashCode] = false; } }
/// <summary> /// Completes the operation. /// </summary> protected internal override void PerformCompletion() { try { if (_completionAction != null) { _completionAction(this); } } finally { _responseDisposed = true; if (_response != null) { _response.Dispose(); _response = null; } } }
private void Reset() { _operationType = OperationType.None; _oneWayResultAction = null; _roundTripResultAction = null; _messageSent = false; _responseHeader.Clear(); _responseReceived = false; if (_sendData != null) { _sendData.Dispose(); _sendData = null; } if (_responseData != null) { _responseData.Dispose(); _responseData = null; } }
/// <summary> /// <para>Sends the data in <paramref name="sendData"/> to <see cref="EndPoint"/>. /// Calls <paramref name="resultAction"/> when response data has been recieved, /// the operation times-out, or the operation fails.</para> /// </summary> /// <param name="timeout">The time to wait, in milliseconds, before the operation times out.</param> /// <param name="sendData"> /// <para>The data to send. The pool item will be disposed, returned to the owning pool, /// automatically when it is no longer needed. So it is important that consumers do not /// access it after calling this method.</para> /// </param> /// <param name="resultAction"> /// <para>The method that will be called when the end point responds, /// the operation fails, or the operation times out.</para> /// </param> /// <exception cref="ArgumentNullException"> /// <para><paramref name="sendData"/> is <see langword="null"/>.</para> /// </exception> public void SendRoundTripAsync( int timeout, IPoolItem <MemoryStream> sendData, Action <RoundTripAsyncEventArgs> resultAction) { if (sendData == null) { throw new ArgumentNullException("sendData"); } var task = new AsyncSocketTask(this); task.SetEnumerator(GetSendEnumerator( timeout, sendData, OperationType.RoundTrip, resultAction, task.Callback)); task.Execute(true); }
private ICompletion CompleteOperation(bool wasSynchronous) { Debug.Assert(_operationType != OperationType.None, "CompleteOperation called when _operationType was None."); try { if (_timeoutHandle != null && !_timeoutHandle.TrySetComplete()) { SetError(SocketError.TimedOut); } _timeoutHandle = null; if (_operationType == OperationType.OneWay && _oneWayResultAction != null) { return(OneWayAsyncEventArgs.Create(wasSynchronous, _error, _oneWayResultAction)); } if (_operationType == OperationType.RoundTrip && _roundTripResultAction != null) { if (_error == null) { var result = RoundTripAsyncEventArgs.Create(wasSynchronous, null, _responseData, _roundTripResultAction); // don't want _responseData to be returned to the pool // before the consumer has a chance to read it. It will // be disposed when result.Complete() is called. _responseData = null; return(result); } else { return(RoundTripAsyncEventArgs.Create(wasSynchronous, _error, null, _roundTripResultAction)); } } return(null); } finally { Reset(); } }
/// <summary> /// <para>Sends the data in <paramref name="sendData"/> to the remote end point /// specified during construction. Calls <paramref name="resultAction"/> when all data /// has been sent. Please note that this only indicates that the server received the data /// and does not guarantee that data was processed.</para> /// </summary> /// <param name="timeout">The time to wait, in milliseconds, before the operation times out.</param> /// <param name="sendData"> /// <para>The data to send. The pool item will be disposed, returned to the owning pool, /// automatically when it is no longer needed. So it is important that consumers do not /// access it after calling this method.</para> /// </param> /// <param name="resultAction"> /// <para>The method that will be called when the host acknowledges that the data was /// received, the operation fails, or the operation times out.</para> /// </param> /// <exception cref="ArgumentNullException"> /// <para><paramref name="sendData"/> is <see langword="null"/>.</para> /// </exception> public void SendOneWayAsync( int timeout, IPoolItem <MemoryStream> sendData, Action <OneWayAsyncEventArgs> resultAction) { if (sendData == null) { throw new ArgumentNullException("sendData"); } _currentRequestId = Interlocked.Increment(ref _nextRequestId); var task = new AsyncSocketTask(this); task.SetEnumerator(GetSendEnumerator( timeout, sendData, OperationType.OneWay, resultAction, task.Callback)); task.Execute(true); }
public void Populate(T key, IPoolItem <T> original, int count) { if (!_originals.ContainsKey(key)) { _originals.Add(key, original); } if (!_items.ContainsKey(key)) { _items.Add(key, new Stack <IPoolItem <T> >()); } for (var j = 0; j < count; ++j) { var newItem = original.Replicate(); newItem.GameObject.transform.parent = _root; newItem.GameObject.SetActive(false); newItem.PoolOwner = this; newItem.Key = key; _items[key].Push(newItem); } }
internal static void ReturnByte4(IPoolItem <byte[]> item) { _byte4Pool.Return(item); }
private IEnumerator<bool> GetReceiveEnumerator(ParameterlessDelegate callback) { _receiveArgs.UserToken = callback; while (true) { if (_socket.ReceiveAsync(_receiveArgs)) yield return false; if (!ValidateCompletedEvent(_receiveArgs, SocketAsyncOperation.Receive)) yield break; if (_receiveArgs.BytesTransferred == 0) { SetError(SocketError.ConnectionReset); yield break; } if (_operationType != OperationType.RoundTrip) { SetError(new InvalidOperationException("Received data when no round trip operation was pending.")); yield break; } int position = _receiveArgs.Offset; int count = _receiveArgs.BytesTransferred; if (!_responseHeader.IsComplete) { position += _responseHeader.Read(_receiveArgs.Buffer, position, count - position); if (!_responseHeader.IsComplete || count == position) continue; } if (_responseData == null) _responseData = AsyncSocketClient.MemoryPool.Borrow(); int countAvailable = count - position; int countNeeded = _responseHeader.MessageDataLength - (int)_responseData.Item.Length; if (countNeeded <= countAvailable) { _responseData.Item.Write(_receiveArgs.Buffer, position, countNeeded); _responseData.Item.Seek(0, SeekOrigin.Begin); if (_responseHeader.MessageLength == ServerMessage.EmptyReplyMessageLength && ServerMessage.IsEmptyMessage(_responseData.Item.GetBuffer(), (int)_responseData.Item.Position, (int)_responseHeader.MessageLength)) { _responseData.Dispose(); _responseData = null; } _responseReceived = true; } else { _responseData.Item.Write(_receiveArgs.Buffer, position, countAvailable); } if (IsOperationComplete) yield return true; } }
private IEnumerator<bool> GetSendEnumerator( int timeout, IPoolItem<MemoryStream> sendData, OperationType type, Delegate resultAction, ParameterlessDelegate callback) { ValidateSocketForUse(); _sendData = sendData; _operationType = type; if (_operationType == OperationType.OneWay) { _oneWayResultAction = (Action<OneWayAsyncEventArgs>)resultAction; } else if (_operationType == OperationType.RoundTrip) { _roundTripResultAction = (Action<RoundTripAsyncEventArgs>)resultAction; _responseData = AsyncSocketClient.MemoryPool.Borrow(); } else { string message = string.Format("Unexpected operation type '{0}'", type); Debug.Fail(message); SetError(new InvalidOperationException(message)); yield break; } _socketArgs.UserToken = callback; if (_state == State.Uninitialized) { _state = State.Connecting; var connectTimeoutHandle = TaskMonitor.RegisterMonitor(_connectTimeout, _timeoutHandler, null); if (_socket.ConnectAsync(_socketArgs)) yield return false; if (!connectTimeoutHandle.TrySetComplete()) { SetError(SocketError.TimedOut); yield break; } if (!ValidateCompletedEvent(_socketArgs, SocketAsyncOperation.Connect)) yield break; _state = State.Connected; ThreadPool.UnsafeQueueUserWorkItem(o => { var target = (SocketChannel)o; var task = new AsyncSocketTask(this); task.SetEnumerator(target.GetReceiveEnumerator(task.Callback)); task.Execute(false); }, this); } Debug.Assert(_sendData != null, "_sendData was not set prior to starting the send enumerator."); _socketArgs.SetBuffer(_sendData.Item.GetBuffer(), (int)_sendData.Item.Position, (int)_sendData.Item.Length); _timeoutHandle = TaskMonitor.RegisterMonitor(timeout, _timeoutHandler, null); if (_socket.SendAsync(_socketArgs)) yield return false; if (!ValidateCompletedEvent(_socketArgs, SocketAsyncOperation.Send)) yield break; _messageSent = true; }
private ICompletion CompleteOperation(bool wasSynchronous) { Debug.Assert(_operationType != OperationType.None, "CompleteOperation called when _operationType was None."); try { if (_timeoutHandle != null && !_timeoutHandle.TrySetComplete()) { SetError(SocketError.TimedOut); } _timeoutHandle = null; if (_operationType == OperationType.OneWay && _oneWayResultAction != null) { return OneWayAsyncEventArgs.Create(wasSynchronous, _error, _oneWayResultAction); } if (_operationType == OperationType.RoundTrip && _roundTripResultAction != null) { if (_error == null) { var result = RoundTripAsyncEventArgs.Create(wasSynchronous, null, _responseData, _roundTripResultAction); // don't want _responseData to be returned to the pool // before the consumer has a chance to read it. It will // be disposed when result.Complete() is called. _responseData = null; return result; } else { return RoundTripAsyncEventArgs.Create(wasSynchronous, _error, null, _roundTripResultAction); } } return null; } finally { Reset(); } }
/// <summary> /// <para>Sends the data in <paramref name="sendData"/> to <see cref="EndPoint"/>. /// Calls <paramref name="resultAction"/> when response data has been recieved, /// the operation times-out, or the operation fails.</para> /// </summary> /// <param name="timeout">The time to wait, in milliseconds, before the operation times out.</param> /// <param name="sendData"> /// <para>The data to send. The pool item will be disposed, returned to the owning pool, /// automatically when it is no longer needed. So it is important that consumers do not /// access it after calling this method.</para> /// </param> /// <param name="resultAction"> /// <para>The method that will be called when the end point responds, /// the operation fails, or the operation times out.</para> /// </param> /// <exception cref="ArgumentNullException"> /// <para><paramref name="sendData"/> is <see langword="null"/>.</para> /// </exception> public void SendRoundTripAsync( int timeout, IPoolItem<MemoryStream> sendData, Action<RoundTripAsyncEventArgs> resultAction) { if (sendData == null) throw new ArgumentNullException("sendData"); var task = new AsyncSocketTask(this); task.SetEnumerator(GetSendEnumerator( timeout, sendData, OperationType.RoundTrip, resultAction, task.Callback)); task.Execute(true); }