/// <summary> /// ћетод, отправл¤ющий клиенту команду и утилизирующий еЄ обратно в буфер /// TODO перенести метод в IRemoteClient /// </summary> /// <param name="client"></param> /// <param name="action"></param> private void SendClientCommand(IRemoteClient client, Action <IRoomCommand> action) { IRoomCommand command = null; try { command = _pool.Get(); action(command); _log.Debug("SendCommand: " + command); client.SendCommand(command); } catch (Exception e) { _pool.Free(command); _log.Error("Error SendCommand:\n" + e.ToString()); } finally { if (command != null) { _pool.Free(command); } } }
public RoomClient(IBaseSocketClient socketClient, IPool <byte[]> bytesPool, IPool <IRoomCommand> poolCommandPool, IProtocolParser protocol) { if (bytesPool == null) { throw new ArgumentNullException(nameof(bytesPool)); } if (poolCommandPool == null) { throw new ArgumentNullException(nameof(poolCommandPool)); } if (protocol == null) { throw new ArgumentNullException(nameof(protocol)); } if (socketClient == null) { throw new ArgumentNullException(nameof(socketClient)); } _protocol = protocol; _poolCommand = poolCommandPool; _baseSocketClient = socketClient; _baseSocketClient.Disconnect += OnDisconnect; _baseSocketClient.AfterSend += (s, e) => bytesPool.Free(e.Buffer); //возвращаем данные в пул после отправки, для повторного использования _baseSocketClient.AfterReceive += OnAfterReceive; }
/// <summary> /// Frees all elements of the given collection. /// </summary> static public void Free <T>(this IPool <T> inThis, ICollection <T> inSrc) where T : class { foreach (var element in inSrc) { inThis.Free(element); } inSrc.Clear(); }
/// <summary> /// Recycles the object. /// </summary> public void Dispose() { if (m_Source != null && m_Obj != null) { m_Source.Free(m_Obj); m_Obj = null; m_Source = null; } }
/// <summary> /// Метод, открепляющий сокет и закрывающий соединения с ним /// </summary> /// <param name="e">Исключение, если оно возникает при работе с сокетом</param> public void Detach(Exception e) { //проверяем, что если сокет отключен, то, ничего не делаем. if (!_attached) { return; } lock (this) { //стандартная двойная проверка с блокировкой if (!_attached) { return; } _attached = false; //очищаем очередь отправки данных на сокете. //раз дошло до этого места, то уже и не судьба - сокет сломан. foreach (var tuple in _sendQueue) { _pool.Free(tuple.Item1); } //удаляем сокет _socket.Dispose(); _isSendComplete = true; //очищаем буффер на прием _pool.Free(_readCommandBuffer); _readCommandBuffer = null; //очищаем очередь _sendQueue.Clear(); _socket = null; _offset = 0; //вызываем событие дисконнекта сокета Disconnect?.Invoke(this, new UnhandledExceptionEventArgs(e, false)); } }
/// <summary> /// Frees a subsection of the given array. /// </summary> static public void Free <T>(this IPool <T> inThis, T[] inSrc, int inStartIndex, int inCount) where T : class { for (int i = 0; i < inCount; ++i) { int idx = inStartIndex + i; T element = inSrc[idx]; if (element != null) { inThis.Free(element); inSrc[idx] = null; } } }
private void RequestInstancesAndFree(IPool <Bar> pool, int count) { Bar[] instances = new Bar[count]; for (int i = 0; i < count; i++) { instances[i] = pool.New(); } foreach (var bizthing in instances) { pool.Free(bizthing); } }
private void DoCommandProcess(IRoomCommand command) { try { //возбуждаем событие приема команды AfterReceive?.Invoke(this, command); } catch (Exception e) { LogException(e); } finally { //отправляем команду обратно в пул на переиспользование _poolCommand.Free(command); } }
/// <summary> /// ћетод, удал¤ет комнату по еЄ идентификатору /// </summary> /// <param name="roomChannel"></param> /// <param name="reason"></param> public void FreeRoom(IRoomChannel roomChannel, RoomRemoveReason reason) { bool successRemove; lock (_channels) successRemove = _channels.Remove(roomChannel.RoomId); //провер¤ем, что комната уже удалена if (successRemove) { _log.Info("Free roomId: " + roomChannel.RoomId + " reason: " + reason); foreach (var roomChannelClient in roomChannel.Clients) { roomChannelClient.Detach(); } _poolChannels.Free(roomChannel); } }
/// <summary> /// ћетод возвращает кортеж, состо¤щий из ссылки на массив и количества записанных в массив байт. /// ¬озвращенный массив нужно будет передать обратно в IPool<bytes[]>, так как он беретс¤ из пула /// </summary> /// <param name="command">“ранслируема¤ команда</param> /// <returns>ћассив бйат и количество записанных в него байт, начина¤ с индекса 0</returns> public Tuple <byte[], int> ToBuffer(IRoomCommand command) { if (command == null) { throw new ArgumentNullException(nameof(command)); } var sb = _stringPool.Get(); //записываем заголовок команды sb.Append(command.Command); sb.Append("|"); foreach (var pair in command.Data) { //записываем значени¤ из команды sb.Append(pair.Key); sb.Append("^"); sb.Append(pair.Value); sb.Append("|"); } //добавл¤ем хвост sb.Append('\0'); //сохран¤ем команду в строке var value = sb.ToString(); //отдаем обратно билдер sb.Length = 0; _stringPool.Free(sb); //записываем в выделенный буффер данные var buffer = _bytesPool.Get(); var length = Encoding.UTF8.GetBytes(value, 0, value.Length, buffer, 0); return(new Tuple <byte[], int>(buffer, length)); }
public static void Free(T t) { pool.Free(t); }