private void ActivityChanging(AsyncLocalValueChangedArgs <ActivityTracker.ActivityInfo> args)
 {
     if (args.PreviousValue == args.CurrentValue)
     {
         return;
     }
     if (args.CurrentValue != null)
     {
         EventSource.SetCurrentThreadActivityId(args.CurrentValue.ActivityId);
     }
     else
     {
         EventSource.SetCurrentThreadActivityId(Guid.Empty);
     }
 }
 // Token: 0x06003320 RID: 13088 RVA: 0x000C2668 File Offset: 0x000C0868
 private void ActivityChanging(AsyncLocalValueChangedArgs <ActivityTracker.ActivityInfo> args)
 {
     ActivityTracker.ActivityInfo activityInfo  = args.CurrentValue;
     ActivityTracker.ActivityInfo previousValue = args.PreviousValue;
     if (previousValue != null && previousValue.m_creator == activityInfo && (activityInfo == null || previousValue.m_activityIdToRestore != activityInfo.ActivityId))
     {
         EventSource.SetCurrentThreadActivityId(previousValue.m_activityIdToRestore);
         return;
     }
     while (activityInfo != null)
     {
         if (activityInfo.m_stopped == 0)
         {
             EventSource.SetCurrentThreadActivityId(activityInfo.ActivityId);
             return;
         }
         activityInfo = activityInfo.m_creator;
     }
 }
Exemple #3
0
        // This callback is used to initialize the m_current AsyncLocal Variable.
        // Its job is to keep the ETW Activity ID (part of thread local storage) in sync
        // with m_current.ActivityID
        //
        // WARNING: When mixing manual usage of EventSource.SetCurrentThreadActivityID
        // and Start/Stop EventSource events I can't identify a clear design how this
        // synchronization is intended to work. For example code that changes
        // SetCurrentThreadActivityID after a FooStart() event will not flow the
        // explicit ID with the async work, but if FooStart() event is called after
        // SetCurrentThreadActivityID then the explicit ID change does flow.
        // For now I've adopted the approach:
        // Priority 1: Make the API predictable/sensible when only Start/Stop events
        // are in use.
        // Priority 2: If users aren't complaining and it doesn't interfere with
        // goal #1, try to preserve the arbitrary/buggy? existing behavior
        // for mixed usage of SetActivityID + events.
        //
        // For scenarios that only use start/stop events this is what we expect:
        // calling start -> push new ID on stack and update thread-local to match new ID
        // calling stop -> pop ID from stack and update thread-local to match new topmost
        //                 still active ID. If there is none, set ID to zero
        // thread swap -> update thread-local to match topmost active ID.
        //                 If there is none, set ID to zero.
        private void ActivityChanging(AsyncLocalValueChangedArgs <ActivityInfo?> args)
        {
            ActivityInfo?cur  = args.CurrentValue;
            ActivityInfo?prev = args.PreviousValue;

            // Special case only relevant for mixed SetActivityID usage:
            //
            // Are we MAYBE popping off a value?   (we have a prev, and it creator is cur)
            // We can't be certain this is a pop because a thread swapping between two
            // ExecutionContexts can also appear the same way.
            // Then check if we should use the GUID at the time of the start event
            if (prev != null && prev.m_creator == cur)
            {
                // If the saved activity ID is not the same as the creator activity
                // that takes precedence (it means someone explicitly did a SetActivityID)
                // Set it to that and get out
                if (cur == null || prev.m_activityIdToRestore != cur.ActivityId)
                {
                    EventSource.SetCurrentThreadActivityId(prev.m_activityIdToRestore);
                    return;
                }
            }

            // Set the activity to current ActivityInfo.  However that activity
            // might be dead, in which case we should skip it, so we never set
            // the ID to dead things.
            while (cur != null)
            {
                // We found a live activity (typically the first time), set it to that.
                if (cur.m_stopped == 0)
                {
                    EventSource.SetCurrentThreadActivityId(cur.ActivityId);
                    return;
                }
                cur = cur.m_creator;
            }

            // we can get here if there is no information on our activity stack (everything is dead)
            // Set ActivityID to zero
            EventSource.SetCurrentThreadActivityId(Guid.Empty);
        }