diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs
index 91264247bc9539..478029174db339 100644
--- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs
+++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs
@@ -9,6 +9,7 @@
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Converters;
using System.Text.Json.Serialization.Metadata;
+using System.Threading;
namespace System.Text.Json
{
@@ -29,11 +30,14 @@ public sealed partial class JsonSerializerOptions
[RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)]
private static void RootReflectionSerializerDependencies()
{
- if (s_defaultSimpleConverters is null)
+ // s_typeInfoCreationFunc is the last field assigned.
+ // Use it as the sentinel to ensure that all dependencies are initialized.
+ if (Volatile.Read(ref s_typeInfoCreationFunc) is null)
{
s_defaultSimpleConverters = GetDefaultSimpleConverters();
s_defaultFactoryConverters = GetDefaultFactoryConverters();
- s_typeInfoCreationFunc = CreateJsonTypeInfo;
+ // Explicitly ensure that the previous fields are initialized along with this one.
+ Volatile.Write(ref s_typeInfoCreationFunc, CreateJsonTypeInfo);
}
[RequiresUnreferencedCode(JsonSerializer.SerializationUnreferencedCodeMessage)]
diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs
index 95199d7ead9c54..8837b55dcf5da5 100644
--- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs
+++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs
@@ -9,6 +9,7 @@
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
+using System.Threading;
namespace System.Text.Json
{
@@ -579,7 +580,7 @@ internal MemberAccessor MemberAccessorStrategy
///
/// Whether the options instance has been primed for reflection-based serialization.
///
- internal bool IsInitializedForReflectionSerializer { get; private set; }
+ internal bool IsInitializedForReflectionSerializer;
///
/// Initializes the converters for the reflection-based serializer.
@@ -589,7 +590,7 @@ internal MemberAccessor MemberAccessorStrategy
internal void InitializeForReflectionSerializer()
{
RootReflectionSerializerDependencies();
- IsInitializedForReflectionSerializer = true;
+ Volatile.Write(ref IsInitializedForReflectionSerializer, true);
if (_cachingContext != null)
{
_cachingContext.Options.IsInitializedForReflectionSerializer = true;
@@ -610,7 +611,9 @@ private JsonTypeInfo GetJsonTypeInfoFromContextOrCreate(Type type)
return null!;
}
- Debug.Assert(s_typeInfoCreationFunc != null);
+ Debug.Assert(
+ s_typeInfoCreationFunc != null,
+ "Reflection-based JsonTypeInfo creator should be initialized if IsInitializedForReflectionSerializer is true.");
return s_typeInfoCreationFunc(type, this);
}