private void EnqueueRoomEventAction(BigInteger roomId, BigInteger nonce, Func<Task> action) { RoomEventActionsState roomEventActionsState = GetRoomEventActionsState(roomId); lock (roomEventActionsState.RoomEventActions) { roomEventActionsState.RoomEventActions.Add(Tuple.Create(nonce, action)); } }
private RoomEventActionsState GetRoomEventActionsState(BigInteger roomId) { RoomEventActionsState roomEventActionsState; lock (this.roomIdToRoomEventActionsMap) { if (!this.roomIdToRoomEventActionsMap.TryGetValue(roomId, out roomEventActionsState)) { roomEventActionsState = new RoomEventActionsState(); this.roomIdToRoomEventActionsMap.Add(roomId, roomEventActionsState); } } return roomEventActionsState; }
public async void Update() { try { List<Func<Task>> orderedActions = new List<Func<Task>>(); lock (this.roomIdToRoomEventActionsMap) { foreach (KeyValuePair<BigInteger, RoomEventActionsState> roomEventActionsStatePair in this.roomIdToRoomEventActionsMap) { RoomEventActionsState roomEventActionsState = roomEventActionsStatePair.Value; List<Tuple<BigInteger, Func<Task>>> roomEventActions = roomEventActionsState.RoomEventActions; foreach (Tuple<BigInteger, Func<Task>> action in roomEventActions.Where(t => t.Item1 < 0)) { orderedActions.Add(action.Item2); } roomEventActions = roomEventActions.Where(t => t.Item1 >= 0).ToList(); roomEventActionsState.RoomEventActions = roomEventActions; lock (roomEventActions) { if (roomEventActions.Count == 0) continue; if (roomEventActionsState.NextExpectedEventNonce == null) { roomEventActionsState.NextExpectedEventNonce = 0; } BigInteger nextNonce = roomEventActionsState.NextExpectedEventNonce.Value; if (roomEventActions.Find(t => t.Item1 == nextNonce) == null) continue; foreach (Tuple<BigInteger, Func<Task>> action in roomEventActions.OrderBy(t => t.Item1)) { //action.Item2(); orderedActions.Add(action.Item2); roomEventActionsState.NextExpectedEventNonce = action.Item1 + 1; } roomEventActions.Clear(); } } } for (int i = 0; i < orderedActions.Count; i++) { IEnumerable<Task> handlersTasks; lock (orderedActions[i]) { handlersTasks = orderedActions[i] .GetInvocationList() .Cast<Func<Task>>() .Select(handler => handler.Invoke()); } await Task.WhenAll(handlersTasks); } } catch (Exception e) { Debug.LogException(e); } }