diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs index adacabad646bd..00d07fd645b44 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ExecutionContext.cs @@ -25,7 +25,7 @@ namespace System.Threading public sealed class ExecutionContext : IDisposable, ISerializable { internal static readonly ExecutionContext Default = new ExecutionContext(isDefault: true); - internal static readonly ExecutionContext DefaultFlowSuppressed = new ExecutionContext(AsyncLocalValueMap.Empty, Array.Empty(), isFlowSuppressed: true); + private static volatile ExecutionContext? s_defaultFlowSuppressed; private readonly IAsyncLocalValueMap? m_localValues; private readonly IAsyncLocal[]? m_localChangeNotifications; @@ -88,9 +88,11 @@ public void GetObjectData(SerializationInfo info, StreamingContext context) if (m_localValues == null || AsyncLocalValueMap.IsEmpty(m_localValues)) { +#pragma warning disable CA1825 // Avoid unnecessary zero-length array allocations return isFlowSuppressed ? - DefaultFlowSuppressed : + (s_defaultFlowSuppressed ??= new ExecutionContext(AsyncLocalValueMap.Empty, new IAsyncLocal[0], isFlowSuppressed: true)) : null; // implies the default context +#pragma warning restore CA1825 } return new ExecutionContext(m_localValues, m_localChangeNotifications, isFlowSuppressed); diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs index 2dff5a0ce62dd..b51a51269f8d9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Future.cs @@ -61,7 +61,7 @@ public class Task : Task /// A cached task for default(TResult). internal static readonly Task s_defaultResultTask = TaskCache.CreateCacheableTask(default); - private static readonly TaskFactory s_Factory = new TaskFactory(); + private static TaskFactory? s_Factory; // The value itself, if set. internal TResult? m_result; @@ -486,7 +486,10 @@ internal TResult GetResultCore(bool waitCompletionNotification) /// of , as would result from using /// the default constructor on the factory type. /// - public static new TaskFactory Factory => s_Factory; + public static new TaskFactory Factory => + Volatile.Read(ref s_Factory) ?? + Interlocked.CompareExchange(ref s_Factory, new TaskFactory(), null) ?? + s_Factory; /// /// Evaluates the value selector of the Task which is passed in as an object and stores the result.