Пример #1
0
        /// <summary>
        /// Attempts to execute the delegate immediately, on the calling thread, without scheduling.
        /// </summary>
        /// <typeparam name="T">Action argument type.</typeparam>
        /// <param name="synchronizationObject">Synchronization object.</param>
        /// <param name="action">Action to execute.</param>
        /// <param name="argument">Action argument.</param>
        /// <param name="startTime">Scheduled start time.</param>
        /// <param name="context">The scheduler context on which to execute the action.</param>
        /// <returns>Success flag.</returns>
        public bool TryExecute <T>(SynchronizationLock synchronizationObject, Action <T> action, T argument, DateTime startTime, SchedulerContext context)
        {
            if (this.forcedShutdownRequested || startTime > context.FinalizeTime)
            {
                return(true);
            }

            if (startTime > this.clock.GetCurrentTime() && this.delayFutureWorkitemsUntilDue)
            {
                return(false);
            }

            if (!this.isSchedulerThread.Value && !this.allowSchedulingOnExternalThreads)
            {
                // this thread is not ours, so return
                return(false);
            }

            // try to acquire a lock on the sync context
            // however, if this thread already has the lock, we have to give up to keep the no-reentrancy guarantee
            if (!synchronizationObject.TryLock())
            {
                return(false);
            }

            try
            {
                // Unlike ExecuteAndRelease, which assumes that the context has already been entered (e.g.
                // when the work item was first created), we need to explicitly enter the context prior to
                // running the action. The context will be exited in the finally clause.
                context.Enter();

                action(argument);
                this.counters?.Increment(SchedulerCounters.WorkitemsPerSecond);

                this.counters?.Increment(SchedulerCounters.ImmediateWorkitemsPerSecond);
            }
            catch (Exception e) when(this.errorHandler(e))
            {
            }
            finally
            {
                synchronizationObject.Release();
                context.Exit();
            }

            return(true);
        }
Пример #2
0
 private void ExecuteAndRelease(SynchronizationLock synchronizationObject, Action action, SchedulerContext context)
 {
     try
     {
         action();
         this.counters?.Increment(SchedulerCounters.WorkitemsPerSecond);
     }
     catch (Exception e) when(this.errorHandler(e))
     {
     }
     finally
     {
         synchronizationObject.Release();
         context.Exit();
     }
 }