diff --git a/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.Current.net45.cs b/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.Current.net45.cs index e1ce4ca6dead..21fbee09a603 100644 --- a/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.Current.net45.cs +++ b/src/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.Current.net45.cs @@ -2,13 +2,12 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Runtime.Remoting; using System.Runtime.Remoting.Messaging; using System.Security; namespace System.Diagnostics { - // this code is specific to .NET 4.5 and uses CallContext to store Activity.Current which requires Activity to be Serializable. - [Serializable] // DO NOT remove public partial class Activity { /// @@ -22,7 +21,14 @@ public static Activity Current #endif get { - return (Activity)CallContext.LogicalGetData(FieldKey); + ObjectHandle activityHandle = (ObjectHandle)CallContext.LogicalGetData(FieldKey); + + // Unwrap the Activity if it was set in the same AppDomain (as FieldKey is AppDomain-specific). + if (activityHandle != null) + { + return (Activity)activityHandle.Unwrap(); + } + return null; } #if ALLOW_PARTIALLY_TRUSTED_CALLERS @@ -30,18 +36,23 @@ public static Activity Current #endif private set { - CallContext.LogicalSetData(FieldKey, value); + // Applications may implicitly or explicitly call other AppDomains + // that do not have DiagnosticSource DLL, therefore may not be able to resolve Activity type stored in the logical call context. + // To avoid it, we wrap Activity with ObjectHandle. + CallContext.LogicalSetData(FieldKey, new ObjectHandle(value)); } } #region private - [Serializable] // DO NOT remove private partial class KeyValueListNode { } - private static readonly string FieldKey = $"{typeof(Activity).FullName}"; + // Slot name depends on the AppDomain Id in order to prevent AppDomains to use the same Activity + // Cross AppDomain calls are considered as 'external' i.e. only Activity Id and Baggage should be propagated and + // new Activity should be started for the RPC calls (incoming and outgoing) + private static readonly string FieldKey = $"{typeof(Activity).FullName}_{AppDomain.CurrentDomain.Id}"; #endregion } } \ No newline at end of file