/// <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); } }
/// <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(); }); }
public static int GetTaskTracePosition(TaskTrace taskTrace) { int position = 0; position = TraceDAL.GetTaskTracePosition(taskTrace); return(position); }
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); }
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); }
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); }
public static int CreateTaskTrace(TaskTrace taskTrace) { int result = 0; result = TraceDAL.InsertTaskTrace(taskTrace); return(result); }
public static int UpdateTaskTrace(TaskTrace taskTrace) { int result = 0; result = TraceDAL.UpdateTaskTrace(taskTrace); return(result); }
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); } }
/// <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()); }