Esempio n. 1
0
        /// <summary>
        /// Schedules the provided handler on the dispatcher.
        /// </summary>
        /// <param name="priority">The execution priority for the handler</param>
        /// <param name="handler">The handler to execute</param>
        /// <returns>An async operation for the scheduled handler.</returns>
        public UIAsyncOperation RunAsync(CoreDispatcherPriority priority, CancellableDispatchedHandler handler)
        {
            UIAsyncOperation operation = null;

            DispatchedHandler nonCancellableHandler = () => handler(operation.Token);

            return(operation = EnqueueOperation(priority, nonCancellableHandler));
        }
Esempio n. 2
0
        /// <summary>
        /// Run operation with 'animation' priority, prior to layout and draw calls. This will run at the beginning of the next UI pass.
        /// </summary>
        internal UIAsyncOperation RunAnimation(DispatchedHandler handler)
        {
            var operation = new UIAsyncOperation(handler, null);

            ImmutableInterlocked.Enqueue(ref _animationQueue, operation);
            QueueOperations();

            return(operation);
        }
Esempio n. 3
0
        /// <summary>
        /// Schedules the provided handler on the dispatcher.
        /// </summary>
        /// <param name="priority">The execution priority for the handler</param>
        /// <param name="handler">The handler to execute</param>
        /// <returns>An async operation for the scheduled handler.</returns>
        /// <remarks>Can only be invoked on the UI thread</remarks>
        internal UIAsyncOperation RunAsync(CoreDispatcherPriority priority, CancellableDispatchedHandler handler)
        {
            CoreDispatcher.CheckThreadAccess();

            UIAsyncOperation operation = null;

            DispatchedHandler nonCancellableHandler = () => handler(operation.Token);

            return(operation = EnqueueOperation(priority, nonCancellableHandler));
        }
Esempio n. 4
0
        private UIAsyncOperation EnqueueOperation(CoreDispatcherPriority priority, DispatchedHandler handler)
        {
            EventActivity scheduleActivity = null;

            if (_trace.IsEnabled)
            {
                scheduleActivity = _trace.WriteEventActivity(
                    TraceProvider.CoreDispatcher_Schedule,
                    EventOpcode.Send,
                    new[] {
                    ((int)priority).ToString(),
                    handler.Method.DeclaringType.FullName + "." + handler.Method.DeclaringType.Name
                }
                    );
            }

            var operation = new UIAsyncOperation(handler, scheduleActivity);

            if (priority < CoreDispatcherPriority.Idle || priority > CoreDispatcherPriority.High)
            {
                throw new ArgumentException($"The priority {priority} is not supported");
            }

            var queue = GetQueue(priority);

            bool shouldEnqueue;

            lock (_gate)
            {
                queue.Enqueue(operation);
                shouldEnqueue = IncrementGlobalCount() == 1;
            }

            if (shouldEnqueue)
            {
                EnqueueNative();
            }

            return(operation);
        }
Esempio n. 5
0
        private void DispatchItems()
        {
            UIAsyncOperation       operation         = null;
            CoreDispatcherPriority operationPriority = CoreDispatcherPriority.Normal;

            for (int i = 3; i >= 0; i--)
            {
                var queue = _queues[i];

                lock (_gate)
                {
                    if (queue.Count > 0)
                    {
                        operation         = queue.Dequeue();
                        operationPriority = (CoreDispatcherPriority)(i - 2);

                        if (DecrementGlobalCount() > 0)
                        {
                            EnqueueNative();
                        }
                        break;
                    }
                }
            }

            if (operation != null)
            {
                if (!operation.IsCancelled)
                {
                    IDisposable runActivity = null;

                    try
                    {
                        if (_trace.IsEnabled)
                        {
                            runActivity = _trace.WriteEventActivity(
                                TraceProvider.CoreDispatcher_InvokeStart,
                                TraceProvider.CoreDispatcher_InvokeStop,
                                relatedActivity: operation.ScheduleEventActivity,
                                payload: new[] { ((int)operationPriority).ToString(), operation.GetDiagnosticsName() }
                                );
                        }

                        using (runActivity)
                        {
                            using (CoreDispatcherSynchronizationContext.Apply(this, operationPriority))
                            {
                                operation.Action();
                                operation.Complete();
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (_trace.IsEnabled)
                        {
                            _trace.WriteEvent(TraceProvider.CoreDispatcher_Exception, EventOpcode.Send, new[] { ex.GetType().ToString(), operation.GetDiagnosticsName() });
                        }
                        operation.SetError(ex);
                        this.Log().Error("Dispatcher unhandled exception", ex);
                    }
                }
                else
                {
                    if (_trace.IsEnabled)
                    {
                        _trace.WriteEvent(TraceProvider.CoreDispatcher_Cancelled, EventOpcode.Send, new[] { operation.GetDiagnosticsName() });
                    }
                }
            }
            else
            {
                throw new InvalidOperationException("Dispatch queue is empty");
            }
        }
Esempio n. 6
0
        private void DispatchItems()
        {
            UIAsyncOperation operation = null;
            var operationPriority      = CoreDispatcherPriority.Normal;

            Rendering?.Invoke(null, RenderingEventArgsGenerator(DateTimeOffset.UtcNow - _startTime));

            var didEnqueue = false;

            for (var i = 3; i >= 0; i--)
            {
                var queue = _queues[i];

                lock (_gate)
                {
                    if (queue.Count > 0)
                    {
                        operation         = queue.Dequeue();
                        operationPriority = (CoreDispatcherPriority)(i - 2);

                        if (DecrementGlobalCount() > 0)
                        {
                            didEnqueue = true;
                            EnqueueNative();
                        }
                        break;
                    }
                }
            }

            if (operation != null)
            {
                if (!operation.IsCancelled)
                {
                    IDisposable runActivity = null;

                    try
                    {
                        if (_trace.IsEnabled)
                        {
                            runActivity = _trace.WriteEventActivity(
                                TraceProvider.CoreDispatcher_InvokeStart,
                                TraceProvider.CoreDispatcher_InvokeStop,
                                relatedActivity: operation.ScheduleEventActivity,
                                payload: new[] { ((int)operationPriority).ToString(), operation.GetDiagnosticsName() }
                                );
                        }

                        using (runActivity)
                        {
                            using (GetSyncContext(operationPriority).Apply())
                            {
                                operation.Action();
                                operation.Complete();
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (_trace.IsEnabled)
                        {
                            _trace.WriteEvent(TraceProvider.CoreDispatcher_Exception, EventOpcode.Send, new[] { ex.GetType().ToString(), operation.GetDiagnosticsName() });
                        }
                        operation.SetError(ex);
                        this.Log().Error("Dispatcher unhandled exception", ex);
                    }
                }
                else
                {
                    if (_trace.IsEnabled)
                    {
                        _trace.WriteEvent(TraceProvider.CoreDispatcher_Cancelled, EventOpcode.Send, new[] { operation.GetDiagnosticsName() });
                    }
                }
            }
            else if (!ShouldRaiseRenderEvents)
            {
                if (this.Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug))
                {
                    this.Log().Error("Dispatch queue is empty");
                }
            }

            if (!didEnqueue && ShouldRaiseRenderEvents)
            {
                DispatchWakeUp();
            }
        }