示例#1
0
        /// <summary>
        /// Enqueue an event
        /// </summary>
        /// <param name="eventWrapper">an event wrapper</param>
        /// <param name="priority">the queue to enqueue to</param>
        private void Enqueue(EventWrapper <O, E> eventWrapper, byte priority)
        {
            if (priority > m_MaxPriority)
            {
                throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "Max priority is {0} and {1} was requested", m_MaxPriority, priority));
            }
            if (priority < MIN_PRIORITY)
            {
                throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "Min priority is {0} and {1} was requested", MIN_PRIORITY, priority));
            }
            // get the queue that corresponds to this priority
            Queue <EventWrapper <O, E> > eventQueue = m_EventQueues[priority];

            // lock it
            lock (eventQueue)
            {
                // enqueue the event on it
                eventQueue.Enqueue(eventWrapper);
            }
            lock (m_PumpLock)
            {
                if (m_NumPendingEvents == 0 && m_PumpOn)
                {
                    m_NumPendingEvents++;
                    ScheduleHandleNextEvent();
                    return;
                }
                m_NumPendingEvents++;
            }
        }
示例#2
0
        /// <summary>
        /// Post and event
        /// </summary>
        /// <param name="callback"></param>
        /// <param name="anEvent"></param>
        /// <param name="priority"></param>
        /// <returns></returns>
        public Task <IState <O, E> > PostEvent(E anEvent, byte priority)
        {
            // create an AsyncResult for this event
            TaskCompletionSource <IState <O, E> > taskCompletionSource = new TaskCompletionSource <IState <O, E> >(anEvent);
            // wrap the event and the AsycResult together
            EventWrapper <O, E> eventWrapper = new EventWrapper <O, E>(anEvent, taskCompletionSource);

            // post the wrapper on the appropriate queue
            Enqueue(eventWrapper, priority);
            // return the AsyncResult
            return(taskCompletionSource.Task);
        }
示例#3
0
        private async Task HandleNextEvent()
        {
            //Logger.LogVerbose("Dequeue next event for {0}",m_Owner);
            // get the most eligible wrapped event
            EventWrapper <O, E> eventWrapper = Dequeue();

            Debug.Assert(eventWrapper != null);
            IState <O, E> currentState = m_CurrentState;

            // retrieve the corresponding taskCompletionSource
            TaskCompletionSource <IState <O, E> > taskCompletionSource = eventWrapper.TaskCompletionSource;

            try
            {
                // call OnEvent of current state
                IState <O, E> nextState = await currentState.OnEvent(m_Owner, eventWrapper.Event, this);

                // if returned not null
                if (nextState != null)
                {
                    // leave this state and enter the next
                    await currentState.OnExit(m_Owner, nextState, this);

                    m_CurrentState = nextState;
                    await nextState.OnEntry(m_Owner, currentState, this);
                }
                try
                {
                    taskCompletionSource.SetResult(m_CurrentState);
                }
                catch (InvalidOperationException)
                {
                    // This is ok, there is a race condition between timeout and actual completion
                }
            }
            catch (Exception e)
            {
                // deliver the exception to the result
                try
                {
                    taskCompletionSource.SetException(e);
                }
                catch (InvalidOperationException)
                {
                    // This is ok, there is a race condition between timeout and actual completion
                }
            }
            finally
            {
                lock (m_PumpLock)
                {
                    if (m_NumPendingEvents > 0)
                    {
                        m_NumPendingEvents--;
                        if (m_NumPendingEvents > 0 && m_PumpOn)
                        {
                            ScheduleHandleNextEvent();
                        }
                    }
                }
            }
        }