dotnet/runtime

CorrelationManager.LogicalOperationStack.Clone() is shallower than in .NET Framework

Open

#38,176 opened on 2020年6月19日

GitHub で見る
 (10 comments) (0 reactions) (0 assignees)C# (5,445 forks)batch import
area-System.Diagnostics.TraceSourcedocumentationhelp wanted

Repository metrics

Stars
 (17,886 stars)
PR merge metrics
 (平均マージ 12d 11h) (30d で 661 merged PRs)

説明

Description

The Clone method of the Stack returned by CorrelationManager.LogicalOperationStack changed behavior between .NET Framework and .NET Core.

  • In .NET Framework 4.8, Clone returns a new Stack that initially contains the same items as the original, but otherwise works independently. Output from the demo built for net4.8:
    Operations: inner,outer
    Operations: inner,outer
    
  • In .NET Core 2.1, Clone returns a new instance of a class derived from Stack, but if items are later pushed or popped in the original stack, then the clone also updates. Output from the demo built for netcoreapp2.1:
    Operations: inner,outer
    Operations:
    

Source code for the demo:

using System;
using System.Collections;
using System.Diagnostics;
using System.Linq;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Trace.CorrelationManager.StartLogicalOperation("outer");
            Trace.CorrelationManager.StartLogicalOperation("inner");

            var clone = (Stack)Trace.CorrelationManager.LogicalOperationStack.Clone();
            Console.WriteLine("Operations: {0}", string.Join(",", clone.Cast<object>()));

            Trace.CorrelationManager.StopLogicalOperation();
            Trace.CorrelationManager.StopLogicalOperation();

            Console.WriteLine("Operations: {0}", string.Join(",", clone.Cast<object>()));
        }
    }
}

Configuration

.NET Framework 4.8 vs. .NET Core 2.1. Windows 10 version 2004 x64.

Regression?

A difference from .NET Framework, at least. It is not causing any problem for me, but it is a surprise and does not seem to have been documented elsewhere.

Other information

Workaround: call ToArray instead of Clone. GetEnumerator on the array will yield the inmost logical operation first, just like with Clone. In contrast, new Stack(Trace.CorrelationManager.LogicalOperationStack) would reverse the order.

The Clone implementation came from https://github.com/dotnet/corefx/pull/12527#discussion_r83333871.

コントリビューターガイド