TaskScheduler 源代码

#pragma warning disable 0420
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using System.Security;
using System.Security.Permissions;
using System.Collections.Concurrent;
using System.Diagnostics.Contracts;
using System.Diagnostics;
using System.Runtime.CompilerServices;
 
namespace System.Threading.Tasks
{
 
    [DebuggerDisplay("Id={Id}")]
    [DebuggerTypeProxy(typeof(SystemThreadingTasks_TaskSchedulerDebugView))]
    [HostProtection(Synchronization = true, ExternalThreading = true)]
#pragma warning disable 618
    [PermissionSet(SecurityAction.InheritanceDemand, Unrestricted = true)]
#pragma warning restore 618
    public abstract class TaskScheduler
    {
        
        [SecurityCritical]
        protected internal abstract void QueueTask(Task task);
         
        [SecurityCritical]
        protected abstract bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued);
         
        [SecurityCritical]
        protected abstract IEnumerable<Task> GetScheduledTasks();
   
        public virtual Int32 MaximumConcurrencyLevel
        {
            get
            {
                return Int32.MaxValue;
            }
        }
 
        
        [SecuritySafeCritical]
        internal bool TryRunInline(Task task, bool taskWasPreviouslyQueued)
        {
            TaskScheduler ets = task.ExecutingTaskScheduler;
            
            if(ets != this && ets !=null) return ets.TryRunInline(task, taskWasPreviouslyQueued);
 
            StackGuard currentStackGuard;
            if( (ets == null) ||
                (task.m_action == null) ||
                task.IsDelegateInvoked || 
                task.IsCanceled ||
                (currentStackGuard = Task.CurrentStackGuard).TryBeginInliningScope() == false)
            {
                return false;
            }
            
            bool bInlined = false;
            try
            {
                task.FireTaskScheduledIfNeeded(this);
                bInlined = TryExecuteTaskInline(task, taskWasPreviouslyQueued);
            }
            finally
            {
                currentStackGuard.EndInliningScope();
            }
 
            if (bInlined && !(task.IsDelegateInvoked || task.IsCanceled)) 
            {
                throw new InvalidOperationException(Environment.GetResourceString("TaskScheduler_InconsistentStateAfterTryExecuteTaskInline"));
            }
 
            return bInlined;
        }
 
        [SecurityCritical]
        protected internal virtual bool TryDequeue(Task task)
        {
            return false;
        }
 
        internal virtual void NotifyWorkItemProgress()
        { 
        }
 
        internal virtual bool RequiresAtomicStartTransition
        {
            get { return true; }
        }
 
        [SecurityCritical]
        internal void InternalQueueTask(Task task)
        {
            Contract.Requires(task != null);
 
            task.FireTaskScheduledIfNeeded(this);
 
            this.QueueTask(task);
        }
 
 
        private static readonly ConditionalWeakTable<TaskScheduler, object> s_activeTaskSchedulers = new ConditionalWeakTable<TaskScheduler,object>();
        
        private static readonly TaskScheduler s_defaultTaskScheduler = new ThreadPoolTaskScheduler();
 
        internal static int s_taskSchedulerIdCounter;
 
        private volatile int m_taskSchedulerId;
 

        protected TaskScheduler()
        {
            Contract.Assert(s_activeTaskSchedulers != null, "Expected non-null s_activeTaskSchedulers");
            s_activeTaskSchedulers.Add(this, null);
        } 
        
        public static TaskScheduler Default 
        {
            get
            {
                return s_defaultTaskScheduler;
            }
        }
        
        public static TaskScheduler Current 
        {
            get
            {
                TaskScheduler current = InternalCurrent;
                return current ?? TaskScheduler.Default;
            }
        } 
        
        internal static TaskScheduler InternalCurrent
        {
            get
            {
                Task currentTask = Task.InternalCurrent;
                return ( (currentTask != null) 
                    && ((currentTask.CreationOptions & TaskCreationOptions.HideScheduler) == 0)
                    ) ? currentTask.ExecutingTaskScheduler : null;
            }
        }
 
        
        public static TaskScheduler FromCurrentSynchronizationContext()
        {
            return new SynchronizationContextTaskScheduler();
        }
 
        
        public Int32 Id
        {
            get
            {
                if (m_taskSchedulerId == 0)
                {
                    int newId = 0;
 
                    do
                    {
                        newId = Interlocked.Increment(ref s_taskSchedulerIdCounter);
                    } while (newId == 0);
                    
                    Interlocked.CompareExchange(ref m_taskSchedulerId, newId, 0);
                }
 
                return m_taskSchedulerId;
            }
        }
 
        
        [SecurityCritical]
        protected bool TryExecuteTask(Task task)
        {
            if (task.ExecutingTaskScheduler != this)
            {
                throw new InvalidOperationException(Environment.GetResourceString("TaskScheduler_ExecuteTask_WrongTaskScheduler"));
            }
 
            return task.ExecuteEntry(true);
        }

        private static EventHandler<UnobservedTaskExceptionEventArgs> _unobservedTaskException;
        private static readonly object _unobservedTaskExceptionLockObject = new object();
 
        
        public static event EventHandler<UnobservedTaskExceptionEventArgs> UnobservedTaskException
        {
            [System.Security.SecurityCritical]
            add
            {
                if (value != null)
                {
#if !PFX_LEGACY_3_5
                    RuntimeHelpers.PrepareContractedDelegate(value);
#endif
                    lock (_unobservedTaskExceptionLockObject) _unobservedTaskException += value;
                }
            }
 
            [System.Security.SecurityCritical]
            remove
            {
                lock (_unobservedTaskExceptionLockObject) _unobservedTaskException -= value;
            }
        }
                    
 
        internal static void PublishUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs ueea)
        {
            lock (_unobservedTaskExceptionLockObject)
            {
                EventHandler<UnobservedTaskExceptionEventArgs> handler = _unobservedTaskException;
                if (handler != null)
                {
                    handler(sender, ueea);
                }
            }
        }
 
        
        [SecurityCritical]
        internal Task[] GetScheduledTasksForDebugger()
        {
            IEnumerable<Task> activeTasksSource = GetScheduledTasks();
 
            if (activeTasksSource == null)
                return null;
 
            Task[] activeTasksArray = activeTasksSource as Task[];
            if (activeTasksArray == null)
            {
                activeTasksArray = (new List<Task>(activeTasksSource)).ToArray();
            }
 
            foreach (Task t in activeTasksArray)
            {
                int tmp = t.Id;
            }
 
            return activeTasksArray;
        }
 
        
        [SecurityCritical]
        internal static TaskScheduler[] GetTaskSchedulersForDebugger()
        {
            Contract.Assert(s_activeTaskSchedulers != null, "Expected non-null s_activeTaskSchedulers");
 
            ICollection<TaskScheduler> schedulers = s_activeTaskSchedulers.Keys;
            var arr = new TaskScheduler[schedulers.Count];
            schedulers.CopyTo(arr, 0);
            foreach (var scheduler in arr)
            {
                Contract.Assert(scheduler != null, "Table returned an incorrect Count or CopyTo failed");
                int tmp = scheduler.Id; 
            }
            return arr;
        }
internal sealed class SystemThreadingTasks_TaskSchedulerDebugView { private readonly TaskScheduler m_taskScheduler; public SystemThreadingTasks_TaskSchedulerDebugView(TaskScheduler scheduler) { m_taskScheduler = scheduler; } public Int32 Id { get { return m_taskScheduler.Id; } } public IEnumerable<Task> ScheduledTasks { [SecurityCritical] get { return m_taskScheduler.GetScheduledTasks(); } } } } internal sealed class SynchronizationContextTaskScheduler : TaskScheduler { private SynchronizationContext m_synchronizationContext; internal SynchronizationContextTaskScheduler() { SynchronizationContext synContext = SynchronizationContext.Current; if (synContext == null) { throw new InvalidOperationException(Environment.GetResourceString("TaskScheduler_FromCurrentSynchronizationContext_NoCurrent")); } m_synchronizationContext = synContext; } [SecurityCritical] protected internal override void QueueTask(Task task) { m_synchronizationContext.Post(s_postCallback, (object)task); } [SecurityCritical] protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) { if (SynchronizationContext.Current == m_synchronizationContext) { return TryExecuteTask(task); } else return false; } [SecurityCritical] protected override IEnumerable<Task> GetScheduledTasks() { return null; } public override Int32 MaximumConcurrencyLevel { get { return 1; } } private static SendOrPostCallback s_postCallback = new SendOrPostCallback(PostCallback); private static void PostCallback(object obj) { Task task = (Task) obj; task.ExecuteEntry(true); } } public class UnobservedTaskExceptionEventArgs : EventArgs { private AggregateException m_exception; internal bool m_observed = false; public UnobservedTaskExceptionEventArgs(AggregateException exception) { m_exception = exception; } public void SetObserved() { m_observed = true; } public bool Observed { get { return m_observed; } } public AggregateException Exception { get { return m_exception; } } } }

 

posted @ 2016-09-07 12:16  茗::流  阅读(267)  评论(0)    收藏  举报
如有雷同,纯属参考。如有侵犯你的版权,请联系我。