1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 using System
.Runtime
.CompilerServices
;
6 using System
.Diagnostics
.Tracing
;
7 using Internal
.Runtime
.CompilerServices
;
9 namespace System
.Threading
.Tasks
11 /// <summary>Provides an event source for tracing TPL information.</summary>
13 Name
= "System.Threading.Tasks.TplEventSource",
14 Guid
= "2e5dba47-a3d2-4d16-8ee0-6671ffdcd7b5",
15 LocalizationResources
=
17 "System.Private.CoreLib.Resources.Strings"
22 internal sealed class TplEventSource
: EventSource
24 /// Used to determine if tasks should generate Activity IDs for themselves
25 internal bool TasksSetActivityIds
; // This keyword is set
27 private bool DebugActivityId
;
29 private const int DefaultAppDomainID
= 1;
32 /// Get callbacks when the ETW sends us commands`
34 protected override void OnEventCommand(EventCommandEventArgs command
)
36 // To get the AsyncCausality events, we need to inform the AsyncCausalityTracer
37 if (command
.Command
== EventCommand
.Enable
)
38 AsyncCausalityTracer
.EnableToETW(true);
39 else if (command
.Command
== EventCommand
.Disable
)
40 AsyncCausalityTracer
.EnableToETW(false);
42 if (IsEnabled(EventLevel
.Informational
, Keywords
.TasksFlowActivityIds
))
43 ActivityTracker
.Instance
.Enable();
45 TasksSetActivityIds
= IsEnabled(EventLevel
.Informational
, Keywords
.TasksSetActivityIds
);
47 Debug
= IsEnabled(EventLevel
.Informational
, Keywords
.Debug
);
48 DebugActivityId
= IsEnabled(EventLevel
.Informational
, Keywords
.DebugActivityId
);
52 /// Defines the singleton instance for the TPL ETW provider.
53 /// The TPL Event provider GUID is {2e5dba47-a3d2-4d16-8ee0-6671ffdcd7b5}.
55 public static readonly TplEventSource Log
= new TplEventSource();
57 /// <summary>Prevent external instantiation. All logging should go through the Log instance.</summary>
58 private TplEventSource() : base(new Guid(0x2e5dba47, 0xa3d2, 0x4d16, 0x8e, 0xe0, 0x66, 0x71, 0xff, 0xdc, 0xd7, 0xb5), "System.Threading.Tasks.TplEventSource") { }
60 /// <summary>Configured behavior of a task wait operation.</summary>
61 public enum TaskWaitBehavior
: int
63 /// <summary>A synchronous wait.</summary>
65 /// <summary>An asynchronous await.</summary>
69 /// <summary>ETW tasks that have start/stop events.</summary>
70 public static class Tasks
// this name is important for EventSource
72 /// <summary>A parallel loop.</summary>
73 public const EventTask Loop
= (EventTask
)1;
74 /// <summary>A parallel invoke.</summary>
75 public const EventTask Invoke
= (EventTask
)2;
76 /// <summary>Executing a Task.</summary>
77 public const EventTask TaskExecute
= (EventTask
)3;
78 /// <summary>Waiting on a Task.</summary>
79 public const EventTask TaskWait
= (EventTask
)4;
80 /// <summary>A fork/join task within a loop or invoke.</summary>
81 public const EventTask ForkJoin
= (EventTask
)5;
82 /// <summary>A task is scheduled to execute.</summary>
83 public const EventTask TaskScheduled
= (EventTask
)6;
84 /// <summary>An await task continuation is scheduled to execute.</summary>
85 public const EventTask AwaitTaskContinuationScheduled
= (EventTask
)7;
87 /// <summary>AsyncCausalityFunctionality.</summary>
88 public const EventTask TraceOperation
= (EventTask
)8;
89 public const EventTask TraceSynchronousWork
= (EventTask
)9;
92 public static class Keywords
// this name is important for EventSource
95 /// Only the most basic information about the workings of the task library
96 /// This sets activity IDS and logs when tasks are schedules (or waits begin)
97 /// But are otherwise silent
99 public const EventKeywords TaskTransfer
= (EventKeywords
)1;
101 /// TaskTranser events plus events when tasks start and stop
103 public const EventKeywords Tasks
= (EventKeywords
)2;
105 /// Events associted with the higher level parallel APIs
107 public const EventKeywords Parallel
= (EventKeywords
)4;
109 /// These are relatively verbose events that effectively just redirect
110 /// the windows AsyncCausalityTracer to ETW
112 public const EventKeywords AsyncCausalityOperation
= (EventKeywords
)8;
113 public const EventKeywords AsyncCausalityRelation
= (EventKeywords
)0x10;
114 public const EventKeywords AsyncCausalitySynchronousWork
= (EventKeywords
)0x20;
117 /// Emit the stops as well as the schedule/start events
119 public const EventKeywords TaskStops
= (EventKeywords
)0x40;
122 /// TasksFlowActivityIds indicate that activity ID flow from one task
123 /// to any task created by it.
125 public const EventKeywords TasksFlowActivityIds
= (EventKeywords
)0x80;
128 /// Events related to the happenings of async methods.
130 public const EventKeywords AsyncMethod
= (EventKeywords
)0x100;
133 /// TasksSetActivityIds will cause the task operations to set Activity Ids
134 /// This option is incompatible with TasksFlowActivityIds flow is ignored
135 /// if that keyword is set. This option is likely to be removed in the future
137 public const EventKeywords TasksSetActivityIds
= (EventKeywords
)0x10000;
140 /// Relatively Verbose logging meant for debugging the Task library itself. Will probably be removed in the future
142 public const EventKeywords Debug
= (EventKeywords
)0x20000;
144 /// Relatively Verbose logging meant for debugging the Task library itself. Will probably be removed in the future
146 public const EventKeywords DebugActivityId
= (EventKeywords
)0x40000;
149 //-----------------------------------------------------------------------------------
151 // TPL Event IDs (must be unique)
154 /// <summary>A task is scheduled to a task scheduler.</summary>
155 private const int TASKSCHEDULED_ID
= 7;
156 /// <summary>A task is about to execute.</summary>
157 private const int TASKSTARTED_ID
= 8;
158 /// <summary>A task has finished executing.</summary>
159 private const int TASKCOMPLETED_ID
= 9;
160 /// <summary>A wait on a task is beginning.</summary>
161 private const int TASKWAITBEGIN_ID
= 10;
162 /// <summary>A wait on a task is ending.</summary>
163 private const int TASKWAITEND_ID
= 11;
164 /// <summary>A continuation of a task is scheduled.</summary>
165 private const int AWAITTASKCONTINUATIONSCHEDULED_ID
= 12;
166 /// <summary>A continuation of a taskWaitEnd is complete </summary>
167 private const int TASKWAITCONTINUATIONCOMPLETE_ID
= 13;
168 /// <summary>A continuation of a taskWaitEnd is complete </summary>
169 private const int TASKWAITCONTINUATIONSTARTED_ID
= 19;
171 private const int TRACEOPERATIONSTART_ID
= 14;
172 private const int TRACEOPERATIONSTOP_ID
= 15;
173 private const int TRACEOPERATIONRELATION_ID
= 16;
174 private const int TRACESYNCHRONOUSWORKSTART_ID
= 17;
175 private const int TRACESYNCHRONOUSWORKSTOP_ID
= 18;
178 //-----------------------------------------------------------------------------------
183 // These are all verbose events, so we need to call IsEnabled(EventLevel.Verbose, ALL_KEYWORDS)
184 // call. However since the IsEnabled(l,k) call is more expensive than IsEnabled(), we only want
185 // to incur this cost when instrumentation is enabled. So the Task codepaths that call these
186 // event functions still do the check for IsEnabled()
188 #region TaskScheduled
190 /// Fired when a task is queued to a TaskScheduler.
192 /// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
193 /// <param name="OriginatingTaskID">The task ID.</param>
194 /// <param name="TaskID">The task ID.</param>
195 /// <param name="CreatingTaskID">The task ID</param>
196 /// <param name="TaskCreationOptions">The options used to create the task.</param>
197 [Event(TASKSCHEDULED_ID
, Task
= Tasks
.TaskScheduled
, Version
= 1, Opcode
= EventOpcode
.Send
,
198 Level
= EventLevel
.Informational
, Keywords
= Keywords
.TaskTransfer
| Keywords
.Tasks
)]
199 public void TaskScheduled(
200 int OriginatingTaskSchedulerID
, int OriginatingTaskID
, // PFX_COMMON_EVENT_HEADER
201 int TaskID
, int CreatingTaskID
, int TaskCreationOptions
, int appDomain
= DefaultAppDomainID
)
203 // IsEnabled() call is an inlined quick check that makes this very fast when provider is off
204 if (IsEnabled() && IsEnabled(EventLevel
.Informational
, Keywords
.TaskTransfer
| Keywords
.Tasks
))
208 EventData
* eventPayload
= stackalloc EventData
[6];
209 eventPayload
[0].Size
= sizeof(int);
210 eventPayload
[0].DataPointer
= ((IntPtr
)(&OriginatingTaskSchedulerID
));
211 eventPayload
[0].Reserved
= 0;
212 eventPayload
[1].Size
= sizeof(int);
213 eventPayload
[1].DataPointer
= ((IntPtr
)(&OriginatingTaskID
));
214 eventPayload
[1].Reserved
= 0;
215 eventPayload
[2].Size
= sizeof(int);
216 eventPayload
[2].DataPointer
= ((IntPtr
)(&TaskID
));
217 eventPayload
[2].Reserved
= 0;
218 eventPayload
[3].Size
= sizeof(int);
219 eventPayload
[3].DataPointer
= ((IntPtr
)(&CreatingTaskID
));
220 eventPayload
[3].Reserved
= 0;
221 eventPayload
[4].Size
= sizeof(int);
222 eventPayload
[4].DataPointer
= ((IntPtr
)(&TaskCreationOptions
));
223 eventPayload
[4].Reserved
= 0;
224 eventPayload
[5].Size
= sizeof(int);
225 eventPayload
[5].DataPointer
= ((IntPtr
)(&appDomain
));
226 eventPayload
[5].Reserved
= 0;
227 if (TasksSetActivityIds
)
229 Guid childActivityId
= CreateGuidForTaskID(TaskID
);
230 WriteEventWithRelatedActivityIdCore(TASKSCHEDULED_ID
, &childActivityId
, 6, eventPayload
);
233 WriteEventCore(TASKSCHEDULED_ID
, 6, eventPayload
);
241 /// Fired just before a task actually starts executing.
243 /// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
244 /// <param name="OriginatingTaskID">The task ID.</param>
245 /// <param name="TaskID">The task ID.</param>
246 [Event(TASKSTARTED_ID
,
247 Level
= EventLevel
.Informational
, Keywords
= Keywords
.Tasks
)]
248 public void TaskStarted(
249 int OriginatingTaskSchedulerID
, int OriginatingTaskID
, // PFX_COMMON_EVENT_HEADER
252 if (IsEnabled(EventLevel
.Informational
, Keywords
.Tasks
))
253 WriteEvent(TASKSTARTED_ID
, OriginatingTaskSchedulerID
, OriginatingTaskID
, TaskID
);
257 #region TaskCompleted
259 /// Fired right after a task finished executing.
261 /// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
262 /// <param name="OriginatingTaskID">The task ID.</param>
263 /// <param name="TaskID">The task ID.</param>
264 /// <param name="IsExceptional">Whether the task completed due to an error.</param>
265 [Event(TASKCOMPLETED_ID
, Version
= 1,
266 Level
= EventLevel
.Informational
, Keywords
= Keywords
.TaskStops
)]
267 public void TaskCompleted(
268 int OriginatingTaskSchedulerID
, int OriginatingTaskID
, // PFX_COMMON_EVENT_HEADER
269 int TaskID
, bool IsExceptional
)
271 if (IsEnabled(EventLevel
.Informational
, Keywords
.Tasks
))
275 EventData
* eventPayload
= stackalloc EventData
[4];
276 int isExceptionalInt
= IsExceptional
? 1 : 0;
277 eventPayload
[0].Size
= sizeof(int);
278 eventPayload
[0].DataPointer
= ((IntPtr
)(&OriginatingTaskSchedulerID
));
279 eventPayload
[0].Reserved
= 0;
280 eventPayload
[1].Size
= sizeof(int);
281 eventPayload
[1].DataPointer
= ((IntPtr
)(&OriginatingTaskID
));
282 eventPayload
[1].Reserved
= 0;
283 eventPayload
[2].Size
= sizeof(int);
284 eventPayload
[2].DataPointer
= ((IntPtr
)(&TaskID
));
285 eventPayload
[2].Reserved
= 0;
286 eventPayload
[3].Size
= sizeof(int);
287 eventPayload
[3].DataPointer
= ((IntPtr
)(&isExceptionalInt
));
288 eventPayload
[3].Reserved
= 0;
289 WriteEventCore(TASKCOMPLETED_ID
, 4, eventPayload
);
295 #region TaskWaitBegin
297 /// Fired when starting to wait for a taks's completion explicitly or implicitly.
299 /// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
300 /// <param name="OriginatingTaskID">The task ID.</param>
301 /// <param name="TaskID">The task ID.</param>
302 /// <param name="Behavior">Configured behavior for the wait.</param>
303 /// <param name="ContinueWithTaskID">
304 /// If known, if 'TaskID' has a 'continueWith' task, mention give its ID here.
305 /// 0 means unknown. This allows better visualization of the common sequential chaining case.
307 [Event(TASKWAITBEGIN_ID
, Version
= 3, Task
= TplEventSource
.Tasks
.TaskWait
, Opcode
= EventOpcode
.Send
,
308 Level
= EventLevel
.Informational
, Keywords
= Keywords
.TaskTransfer
| Keywords
.Tasks
)]
309 public void TaskWaitBegin(
310 int OriginatingTaskSchedulerID
, int OriginatingTaskID
, // PFX_COMMON_EVENT_HEADER
311 int TaskID
, TaskWaitBehavior Behavior
, int ContinueWithTaskID
)
313 if (IsEnabled() && IsEnabled(EventLevel
.Informational
, Keywords
.TaskTransfer
| Keywords
.Tasks
))
317 EventData
* eventPayload
= stackalloc EventData
[5];
318 eventPayload
[0].Size
= sizeof(int);
319 eventPayload
[0].DataPointer
= ((IntPtr
)(&OriginatingTaskSchedulerID
));
320 eventPayload
[0].Reserved
= 0;
321 eventPayload
[1].Size
= sizeof(int);
322 eventPayload
[1].DataPointer
= ((IntPtr
)(&OriginatingTaskID
));
323 eventPayload
[1].Reserved
= 0;
324 eventPayload
[2].Size
= sizeof(int);
325 eventPayload
[2].DataPointer
= ((IntPtr
)(&TaskID
));
326 eventPayload
[2].Reserved
= 0;
327 eventPayload
[3].Size
= sizeof(int);
328 eventPayload
[3].DataPointer
= ((IntPtr
)(&Behavior
));
329 eventPayload
[3].Reserved
= 0;
330 eventPayload
[4].Size
= sizeof(int);
331 eventPayload
[4].DataPointer
= ((IntPtr
)(&ContinueWithTaskID
));
332 eventPayload
[4].Reserved
= 0;
333 if (TasksSetActivityIds
)
335 Guid childActivityId
= CreateGuidForTaskID(TaskID
);
336 WriteEventWithRelatedActivityIdCore(TASKWAITBEGIN_ID
, &childActivityId
, 5, eventPayload
);
340 WriteEventCore(TASKWAITBEGIN_ID
, 5, eventPayload
);
348 /// Fired when the wait for a tasks completion returns.
350 /// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
351 /// <param name="OriginatingTaskID">The task ID.</param>
352 /// <param name="TaskID">The task ID.</param>
353 [Event(TASKWAITEND_ID
,
354 Level
= EventLevel
.Verbose
, Keywords
= Keywords
.Tasks
)]
355 public void TaskWaitEnd(
356 int OriginatingTaskSchedulerID
, int OriginatingTaskID
, // PFX_COMMON_EVENT_HEADER
359 // Log an event if indicated.
360 if (IsEnabled() && IsEnabled(EventLevel
.Verbose
, Keywords
.Tasks
))
361 WriteEvent(TASKWAITEND_ID
, OriginatingTaskSchedulerID
, OriginatingTaskID
, TaskID
);
365 /// Fired when the work (method) associated with a TaskWaitEnd completes
367 /// <param name="TaskID">The task ID.</param>
368 [Event(TASKWAITCONTINUATIONCOMPLETE_ID
,
369 Level
= EventLevel
.Verbose
, Keywords
= Keywords
.TaskStops
)]
370 public void TaskWaitContinuationComplete(int TaskID
)
372 // Log an event if indicated.
373 if (IsEnabled() && IsEnabled(EventLevel
.Verbose
, Keywords
.Tasks
))
374 WriteEvent(TASKWAITCONTINUATIONCOMPLETE_ID
, TaskID
);
378 /// Fired when the work (method) associated with a TaskWaitEnd completes
380 /// <param name="TaskID">The task ID.</param>
381 [Event(TASKWAITCONTINUATIONSTARTED_ID
,
382 Level
= EventLevel
.Verbose
, Keywords
= Keywords
.TaskStops
)]
383 public void TaskWaitContinuationStarted(int TaskID
)
385 // Log an event if indicated.
386 if (IsEnabled() && IsEnabled(EventLevel
.Verbose
, Keywords
.Tasks
))
387 WriteEvent(TASKWAITCONTINUATIONSTARTED_ID
, TaskID
);
391 /// Fired when the an asynchronous continuation for a task is scheduled
393 /// <param name="OriginatingTaskSchedulerID">The scheduler ID.</param>
394 /// <param name="OriginatingTaskID">The task ID.</param>
395 [Event(AWAITTASKCONTINUATIONSCHEDULED_ID
, Task
= Tasks
.AwaitTaskContinuationScheduled
, Opcode
= EventOpcode
.Send
,
396 Level
= EventLevel
.Informational
, Keywords
= Keywords
.TaskTransfer
| Keywords
.Tasks
)]
397 public void AwaitTaskContinuationScheduled(
398 int OriginatingTaskSchedulerID
, int OriginatingTaskID
, // PFX_COMMON_EVENT_HEADER
399 int ContinuwWithTaskId
)
401 if (IsEnabled() && IsEnabled(EventLevel
.Informational
, Keywords
.TaskTransfer
| Keywords
.Tasks
))
405 EventData
* eventPayload
= stackalloc EventData
[3];
406 eventPayload
[0].Size
= sizeof(int);
407 eventPayload
[0].DataPointer
= ((IntPtr
)(&OriginatingTaskSchedulerID
));
408 eventPayload
[0].Reserved
= 0;
409 eventPayload
[1].Size
= sizeof(int);
410 eventPayload
[1].DataPointer
= ((IntPtr
)(&OriginatingTaskID
));
411 eventPayload
[1].Reserved
= 0;
412 eventPayload
[2].Size
= sizeof(int);
413 eventPayload
[2].DataPointer
= ((IntPtr
)(&ContinuwWithTaskId
));
414 eventPayload
[2].Reserved
= 0;
415 if (TasksSetActivityIds
)
417 Guid continuationActivityId
= CreateGuidForTaskID(ContinuwWithTaskId
);
418 WriteEventWithRelatedActivityIdCore(AWAITTASKCONTINUATIONSCHEDULED_ID
, &continuationActivityId
, 3, eventPayload
);
421 WriteEventCore(AWAITTASKCONTINUATIONSCHEDULED_ID
, 3, eventPayload
);
426 [Event(TRACEOPERATIONSTART_ID
, Version
= 1,
427 Level
= EventLevel
.Informational
, Keywords
= Keywords
.AsyncCausalityOperation
)]
428 public void TraceOperationBegin(int TaskID
, string OperationName
, long RelatedContext
)
430 if (IsEnabled() && IsEnabled(EventLevel
.Informational
, Keywords
.AsyncCausalityOperation
))
434 fixed (char* operationNamePtr
= OperationName
)
436 EventData
* eventPayload
= stackalloc EventData
[3];
437 eventPayload
[0].Size
= sizeof(int);
438 eventPayload
[0].DataPointer
= ((IntPtr
)(&TaskID
));
439 eventPayload
[0].Reserved
= 0;
441 eventPayload
[1].Size
= ((OperationName
.Length
+ 1) * 2);
442 eventPayload
[1].DataPointer
= ((IntPtr
)operationNamePtr
);
443 eventPayload
[1].Reserved
= 0;
445 eventPayload
[2].Size
= sizeof(long);
446 eventPayload
[2].DataPointer
= ((IntPtr
)(&RelatedContext
));
447 eventPayload
[2].Reserved
= 0;
448 WriteEventCore(TRACEOPERATIONSTART_ID
, 3, eventPayload
);
454 [Event(TRACEOPERATIONRELATION_ID
, Version
= 1,
455 Level
= EventLevel
.Informational
, Keywords
= Keywords
.AsyncCausalityRelation
)]
456 public void TraceOperationRelation(int TaskID
, CausalityRelation Relation
)
458 if (IsEnabled() && IsEnabled(EventLevel
.Informational
, Keywords
.AsyncCausalityRelation
))
459 WriteEvent(TRACEOPERATIONRELATION_ID
, TaskID
, (int)Relation
); // optimized overload for this exists
462 [Event(TRACEOPERATIONSTOP_ID
, Version
= 1,
463 Level
= EventLevel
.Informational
, Keywords
= Keywords
.AsyncCausalityOperation
)]
464 public void TraceOperationEnd(int TaskID
, AsyncCausalityStatus Status
)
466 if (IsEnabled() && IsEnabled(EventLevel
.Informational
, Keywords
.AsyncCausalityOperation
))
467 WriteEvent(TRACEOPERATIONSTOP_ID
, TaskID
, (int)Status
); // optimized overload for this exists
470 [Event(TRACESYNCHRONOUSWORKSTART_ID
, Version
= 1,
471 Level
= EventLevel
.Informational
, Keywords
= Keywords
.AsyncCausalitySynchronousWork
)]
472 public void TraceSynchronousWorkBegin(int TaskID
, CausalitySynchronousWork Work
)
474 if (IsEnabled() && IsEnabled(EventLevel
.Informational
, Keywords
.AsyncCausalitySynchronousWork
))
475 WriteEvent(TRACESYNCHRONOUSWORKSTART_ID
, TaskID
, (int)Work
); // optimized overload for this exists
478 [Event(TRACESYNCHRONOUSWORKSTOP_ID
, Version
= 1,
479 Level
= EventLevel
.Informational
, Keywords
= Keywords
.AsyncCausalitySynchronousWork
)]
480 public void TraceSynchronousWorkEnd(CausalitySynchronousWork Work
)
482 if (IsEnabled() && IsEnabled(EventLevel
.Informational
, Keywords
.AsyncCausalitySynchronousWork
))
486 EventData
* eventPayload
= stackalloc EventData
[1];
487 eventPayload
[0].Size
= sizeof(int);
488 eventPayload
[0].DataPointer
= ((IntPtr
)(&Work
));
489 eventPayload
[0].Reserved
= 0;
491 WriteEventCore(TRACESYNCHRONOUSWORKSTOP_ID
, 1, eventPayload
);
497 public unsafe void RunningContinuation(int TaskID
, object Object
) { RunningContinuation(TaskID, (long)*((void**)Unsafe.AsPointer(ref Object))); }
498 [Event(20, Keywords
= Keywords
.Debug
)]
499 private void RunningContinuation(int TaskID
, long Object
)
502 WriteEvent(20, TaskID
, Object
);
506 public unsafe void RunningContinuationList(int TaskID
, int Index
, object Object
) { RunningContinuationList(TaskID, Index, (long)*((void**)Unsafe.AsPointer(ref Object))); }
508 [Event(21, Keywords
= Keywords
.Debug
)]
509 public void RunningContinuationList(int TaskID
, int Index
, long Object
)
512 WriteEvent(21, TaskID
, Index
, Object
);
515 [Event(23, Keywords
= Keywords
.Debug
)]
516 public void DebugFacilityMessage(string Facility
, string Message
) { WriteEvent(23, Facility, Message); }
518 [Event(24, Keywords
= Keywords
.Debug
)]
519 public void DebugFacilityMessage1(string Facility
, string Message
, string Value1
) { WriteEvent(24, Facility, Message, Value1); }
521 [Event(25, Keywords
= Keywords
.DebugActivityId
)]
522 public void SetActivityId(Guid NewId
)
525 WriteEvent(25, NewId
);
528 [Event(26, Keywords
= Keywords
.Debug
)]
529 public void NewID(int TaskID
)
532 WriteEvent(26, TaskID
);
536 public void IncompleteAsyncMethod(IAsyncStateMachineBox stateMachineBox
)
538 System
.Diagnostics
.Debug
.Assert(stateMachineBox
!= null);
539 if (IsEnabled(EventLevel
.Warning
, Keywords
.AsyncMethod
))
541 IAsyncStateMachine stateMachine
= stateMachineBox
.GetStateMachineObject();
542 if (stateMachine
!= null)
544 string description
= AsyncMethodBuilderCore
.GetAsyncStateMachineDescription(stateMachine
);
545 IncompleteAsyncMethod(description
);
550 [Event(27, Level
= EventLevel
.Warning
, Keywords
= Keywords
.AsyncMethod
)]
551 private void IncompleteAsyncMethod(string stateMachineDescription
) =>
552 WriteEvent(27, stateMachineDescription
);
555 /// Activity IDs are GUIDS but task IDS are integers (and are not unique across appdomains
556 /// This routine creates a process wide unique GUID given a task ID
558 internal static Guid
CreateGuidForTaskID(int taskID
)
560 // The thread pool generated a process wide unique GUID from a task GUID by
561 // using the taskGuid, the appdomain ID, and 8 bytes of 'randomization' chosen by
562 // using the last 8 bytes as the provider GUID for this provider.
563 // These were generated by CreateGuid, and are reasonably random (and thus unlikely to collide
564 uint pid
= EventSource
.s_currentPid
;
565 return new Guid(taskID
,
566 (short)DefaultAppDomainID
, (short)(DefaultAppDomainID
>> 16),
567 (byte)pid
, (byte)(pid
>> 8), (byte)(pid
>> 16), (byte)(pid
>> 24),
568 0xff, 0xdc, 0xd7, 0xb5);