示例#1
0
        /// <summary>
        /// Schedules a task to the ThreadPool.
        /// </summary>
        /// <param name="task">The task to schedule.</param>
        protected internal override void QueueTask(Task task)
        {
            if (TaskTrace.Enabled)
            {
                Task currentTask  = Task.InternalCurrent;
                Task creatingTask = task.m_parent;

                TaskTrace.TaskScheduled(this.Id, currentTask == null ? 0 : currentTask.Id,
                                        task.Id, creatingTask == null ? 0 : creatingTask.Id,
                                        (int)task.Options);
            }

            if ((task.Options & TaskCreationOptions.LongRunning) != 0)
            {
                // Run LongRunning tasks on their own dedicated thread.
                RuntimeThread thread = RuntimeThread.Create(s_longRunningThreadWork, 0);
                thread.IsBackground = true; // Keep this thread from blocking process shutdown
                thread.Start(task);
            }
            else
            {
                // Normal handling for non-LongRunning tasks.
                bool preferLocal = (task.Options & TaskCreationOptions.PreferFairness) == 0;
                ThreadPool.UnsafeQueueUserWorkItemInternal(task, preferLocal);
            }
        }
示例#2
0
        /// <summary>
        /// Outputs a WaitBegin ETW event, and augments the continuation action to output a WaitEnd ETW event.
        /// </summary>
        /// <param name="task">The task being awaited.</param>
        /// <param name="continuation">The action to invoke when the await operation completes.</param>
        /// <returns>The action to use as the actual continuation.</returns>
        private static Action OutputWaitEtwEvents(Task task, Action continuation)
        {
            Debug.Assert(task != null, "Need a task to wait on");
            Debug.Assert(continuation != null, "Need a continuation to invoke when the wait completes");
            Debug.Assert(TaskTrace.Enabled, "Should only be used when ETW tracing is enabled");

            // ETW event for Task Wait Begin
            var currentTaskAtBegin = Task.InternalCurrent;

            TaskTrace.TaskWaitBegin_Asynchronous(
                (currentTaskAtBegin != null ? currentTaskAtBegin.m_taskScheduler.Id : TaskScheduler.Default.Id),
                (currentTaskAtBegin != null ? currentTaskAtBegin.Id : 0),
                task.Id);

            // Create a continuation action that outputs the end event and then invokes the user
            // provided delegate.  This incurs the allocations for the closure/delegate, but only if the event
            // is enabled, and in doing so it allows us to pass the awaited task's information into the end event
            // in a purely pay-for-play manner (the alternatively would be to increase the size of TaskAwaiter
            // just for this ETW purpose, not pay-for-play, since GetResult would need to know whether a real yield occurred).
            return(() =>
            {
                // ETW event for Task Wait End.
                if (TaskTrace.Enabled)
                {
                    var currentTaskAtEnd = Task.InternalCurrent;
                    TaskTrace.TaskWaitEnd(
                        (currentTaskAtEnd != null ? currentTaskAtEnd.m_taskScheduler.Id : TaskScheduler.Default.Id),
                        (currentTaskAtEnd != null ? currentTaskAtEnd.Id : 0),
                        task.Id);
                }

                // Invoke the original continuation provided to OnCompleted.
                continuation();
            });
        }
示例#3
0
        public static int GetTaskTracePosition(TaskTrace taskTrace)
        {
            int position = 0;

            position = TraceDAL.GetTaskTracePosition(taskTrace);
            return(position);
        }
示例#4
0
        public static int UpdateTaskTrace(TaskTrace taskTrace)
        {
            int updateResult = 0;

            MySqlParameter[] parameters = new MySqlParameter[3];

            parameters[0]       = new MySqlParameter("@mobileindex", MySqlDbType.Int32);
            parameters[0].Value = taskTrace.MobileIndex;

            parameters[1]       = new MySqlParameter("@typeid", MySqlDbType.Int32);
            parameters[1].Value = taskTrace.TypeId;

            parameters[2]       = new MySqlParameter("@position", MySqlDbType.Int32);
            parameters[2].Value = taskTrace.Position;

            try
            {
                updateResult = MySqlHelpers.ExecuteNonQuery(MySqlHelpers.ConnectionString, CommandType.Text, update_trace_sql, parameters);
            }
            catch (Exception ex)
            {
                Console.WriteLine("UpdateTaskTrace EXCEPTION");
                LogUtils.Error($"{ex}");
            }

            return(updateResult);
        }
示例#5
0
        public static int CountTaskTrace(TaskTrace taskTrace)
        {
            int countResult = 0;

            MySqlParameter[] parameters = new MySqlParameter[2];

            parameters[0]       = new MySqlParameter("@mobileindex", MySqlDbType.Int32);
            parameters[0].Value = taskTrace.MobileIndex;

            parameters[1]       = new MySqlParameter("@typeid", MySqlDbType.Int32);
            parameters[1].Value = taskTrace.TypeId;

            try
            {
                countResult = int.Parse(MySqlHelpers.ExecuteScalar(MySqlHelpers.ConnectionString, CommandType.Text, count_trace_sql, parameters).ToString());
            }
            catch (Exception ex)
            {
                Console.WriteLine("CountTaskTrace EXCEPTION");

                LogUtils.Error($"{ex}");
            }

            return(countResult);
        }
示例#6
0
        public static int GetTaskTracePosition(TaskTrace taskTrace)
        {
            int position = 0;

            MySqlParameter[] parameters = new MySqlParameter[2];

            parameters[0]       = new MySqlParameter("@mobileindex", MySqlDbType.Int32);
            parameters[0].Value = taskTrace.MobileIndex;

            parameters[1]       = new MySqlParameter("@typeid", MySqlDbType.Int32);
            parameters[1].Value = taskTrace.TypeId;

            try
            {
                position = (int)MySqlHelpers.ExecuteScalar(MySqlHelpers.ConnectionString, CommandType.Text, get_trace_position_sql, parameters);
            }
            catch (Exception ex)
            {
                Console.WriteLine("GetTaskTracePosition EXCEPTION");

                LogUtils.Error($"{ex}");
            }

            return(position);
        }
示例#7
0
        public static int CreateTaskTrace(TaskTrace taskTrace)
        {
            int result = 0;

            result = TraceDAL.InsertTaskTrace(taskTrace);

            return(result);
        }
示例#8
0
        public static int UpdateTaskTrace(TaskTrace taskTrace)
        {
            int result = 0;

            result = TraceDAL.UpdateTaskTrace(taskTrace);

            return(result);
        }
示例#9
0
        public static int CountTaskTrace(TaskTrace taskTrace)
        {
            int result = 0;

            result = TraceDAL.CountTaskTrace(taskTrace);

            return(result);
        }
        /// <summary>
        /// Schedules a task to the ThreadPool.
        /// </summary>
        /// <param name="task">The task to schedule.</param>
        protected internal override void QueueTask(Task task)
        {
            if (TaskTrace.Enabled)
            {
                Task currentTask  = Task.InternalCurrent;
                Task creatingTask = task.m_parent;

                TaskTrace.TaskScheduled(this.Id, currentTask == null ? 0 : currentTask.Id,
                                        task.Id, creatingTask == null ? 0 : creatingTask.Id,
                                        (int)task.Options);
            }

            if ((task.Options & TaskCreationOptions.LongRunning) != 0)
            {
                ThreadPool.QueueLongRunningWork(() => task.ExecuteEntry(false));
            }
            else
            {
                // Normal handling for non-LongRunning tasks.
                bool forceToGlobalQueue = ((task.Options & TaskCreationOptions.PreferFairness) != 0);
                ThreadPool.UnsafeQueueCustomWorkItem(task, forceToGlobalQueue);
            }
        }
示例#11
0
        /// <summary>
        /// Outputs a WaitBegin ETW event, and augments the continuation action to output a WaitEnd ETW event.
        /// </summary>
        /// <param name="task">The task being awaited.</param>
        /// <param name="continuation">The action to invoke when the await operation completes.</param>
        /// <returns>The action to use as the actual continuation.</returns>
        private static Action OutputWaitEtwEvents(Task task, Action continuation)
        {
            Debug.Assert(task != null, "Need a task to wait on");
            Debug.Assert(continuation != null, "Need a continuation to invoke when the wait completes");
#if CORECLR
            if (Task.s_asyncDebuggingEnabled)
            {
                Task.AddToActiveTasks(task);
            }

            var etwLog = TplEtwProvider.Log;

            if (etwLog.IsEnabled())
            {
                // ETW event for Task Wait Begin
                var currentTaskAtBegin = Task.InternalCurrent;

                // If this task's continuation is another task, get it.
                var continuationTask = AsyncMethodBuilderCore.TryGetContinuationTask(continuation);
                etwLog.TaskWaitBegin(
                    (currentTaskAtBegin != null ? currentTaskAtBegin.m_taskScheduler.Id : TaskScheduler.Default.Id),
                    (currentTaskAtBegin != null ? currentTaskAtBegin.Id : 0),
                    task.Id, TplEtwProvider.TaskWaitBehavior.Asynchronous,
                    (continuationTask != null ? continuationTask.Id : 0));
            }
#else
            Debug.Assert(TaskTrace.Enabled, "Should only be used when ETW tracing is enabled");

            // ETW event for Task Wait Begin
            var currentTaskAtBegin = Task.InternalCurrent;
            TaskTrace.TaskWaitBegin_Asynchronous(
                (currentTaskAtBegin != null ? currentTaskAtBegin.m_taskScheduler.Id : TaskScheduler.Default.Id),
                (currentTaskAtBegin != null ? currentTaskAtBegin.Id : 0),
                task.Id);
#endif

            // Create a continuation action that outputs the end event and then invokes the user
            // provided delegate.  This incurs the allocations for the closure/delegate, but only if the event
            // is enabled, and in doing so it allows us to pass the awaited task's information into the end event
            // in a purely pay-for-play manner (the alternatively would be to increase the size of TaskAwaiter
            // just for this ETW purpose, not pay-for-play, since GetResult would need to know whether a real yield occurred).
#if CORECLR
            return(AsyncMethodBuilderCore.CreateContinuationWrapper(continuation, (innerContinuation, innerTask) =>
            {
                if (Task.s_asyncDebuggingEnabled)
                {
                    Task.RemoveFromActiveTasks(innerTask.Id);
                }

                TplEtwProvider innerEtwLog = TplEtwProvider.Log;

                // ETW event for Task Wait End.
                Guid prevActivityId = new Guid();
                bool bEtwLogEnabled = innerEtwLog.IsEnabled();
                if (bEtwLogEnabled)
                {
                    var currentTaskAtEnd = Task.InternalCurrent;
                    innerEtwLog.TaskWaitEnd(
                        (currentTaskAtEnd != null ? currentTaskAtEnd.m_taskScheduler.Id : TaskScheduler.Default.Id),
                        (currentTaskAtEnd != null ? currentTaskAtEnd.Id : 0),
                        innerTask.Id);

                    // Ensure the continuation runs under the activity ID of the task that completed for the
                    // case the antecedent is a promise (in the other cases this is already the case).
                    if (innerEtwLog.TasksSetActivityIds && (innerTask.Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0)
                    {
                        EventSource.SetCurrentThreadActivityId(TplEtwProvider.CreateGuidForTaskID(innerTask.Id), out prevActivityId);
                    }
                }

                // Invoke the original continuation provided to OnCompleted.
                innerContinuation();

                if (bEtwLogEnabled)
                {
                    innerEtwLog.TaskWaitContinuationComplete(innerTask.Id);
                    if (innerEtwLog.TasksSetActivityIds && (innerTask.Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0)
                    {
                        EventSource.SetCurrentThreadActivityId(prevActivityId);
                    }
                }
            }, task));
#else
            return(() =>
            {
                // ETW event for Task Wait End.
                if (TaskTrace.Enabled)
                {
                    var currentTaskAtEnd = Task.InternalCurrent;
                    TaskTrace.TaskWaitEnd(
                        (currentTaskAtEnd != null ? currentTaskAtEnd.m_taskScheduler.Id : TaskScheduler.Default.Id),
                        (currentTaskAtEnd != null ? currentTaskAtEnd.Id : 0),
                        task.Id);
                }

                // Invoke the original continuation provided to OnCompleted.
                continuation();
            });
#endif
        }
 static ThreadingTracingInitializer()
 {
     TaskTrace.Initialize(new TaskTraceCallbacksImplementation());
     SpinLockTrace.Initialize(new SpinLockTraceCallbacksImplementation());
 }
 /// <summary>
 /// Early library initialization code. StartupCodeInjectorTransform emits calls to these methods
 /// to startupCodeTrigger.InternalInitialize in the toolchain-generated assembly.
 /// BuildDriver.Config defines the ordered list of assemblies to initialize in the method
 /// GetLibraryInitializers().
 /// </summary>
 public static void InitializeLibrary()
 {
     TaskTrace.Initialize(new TaskTraceCallbacksImplementation());
     SpinLockTrace.Initialize(new SpinLockTraceCallbacksImplementation());
 }