class UpdateQueueStatus
{
private static Dictionary<string, UpdateQueueStatus> _mappings = new(StringComparer.OrdinalIgnoreCase);
public static readonly UpdateQueueStatus None = Create(0);
public static readonly UpdateQueueStatus Pending = Create(1);
public static readonly UpdateQueueStatus Queued = Create(0);
public static readonly UpdateQueueStatus Enqueued = Create(1);
public static readonly UpdateQueueStatus Caching = Create(2);
public static readonly UpdateQueueStatus Cached = Create(3);
public static readonly UpdateQueueStatus Applying = Create(4);
public static readonly UpdateQueueStatus Applied = Create(5);
public static readonly UpdateQueueStatus Completed = Create(6);
public static readonly UpdateQueueStatus Failed = Create(7);
public static readonly UpdateQueueStatus Cancelled = Create(8);
public static readonly UpdateQueueStatus Downloading = Create(2);
public string Value { get; }
public UpdateQueueStatus(string value)
{
Value = value;
}
public static UpdateQueueStatus Parse(string value)
{
if (_mappings.TryGetValue(value, out var status))
{
return status;
}
var result = new UpdateQueueStatus(value);
while (true)
{
var currentMap = _mappings;
var newMap = new Dictionary<string, UpdateQueueStatus>(currentMap, StringComparer.OrdinalIgnoreCase);
newMap.TryAdd(value, result);
if (Interlocked.CompareExchange(ref _mappings, newMap, currentMap) == currentMap)
{
break;
}
}
return result;
}
private static UpdateQueueStatus Create(int number, [CallerMemberName] string? name = null)
{
var result = new UpdateQueueStatus(name ?? "None");
_mappings.TryAdd(number.ToString(), result);
_mappings.TryAdd(result.Value, result);
_intMappings.Add((result.Value, number));
return result;
}
}
// Test:
public class Test
{
[Fact]
public void Should_Be_Threadsafe()
{
var count = UpdateQueueStatus.GetMappings().Count;
var tasks = new List<Task>();
for (int i = 0; i < 100; i++)
{
var task = Task.Run(() =>
{
for (int j = 0; j < 100; j++)
{
UpdateQueueStatus.Parse("value" + j);
}
});
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
//Console.WriteLine("Number of keys in the dictionary: " + UpdateQueueStatus.GetMappings());
Assert.Equal(count + 100, UpdateQueueStatus.GetMappings().Count);
}
}
class UpdateQueueStatus
{
private static Dictionary<string, UpdateQueueStatus> _mappings = new(StringComparer.OrdinalIgnoreCase);
public static readonly UpdateQueueStatus None = Create(0);
public static readonly UpdateQueueStatus Pending = Create(1);
public static readonly UpdateQueueStatus Queued = Create(0);
public static readonly UpdateQueueStatus Enqueued = Create(1);
public static readonly UpdateQueueStatus Caching = Create(2);
public static readonly UpdateQueueStatus Cached = Create(3);
public static readonly UpdateQueueStatus Applying = Create(4);
public static readonly UpdateQueueStatus Applied = Create(5);
public static readonly UpdateQueueStatus Completed = Create(6);
public static readonly UpdateQueueStatus Failed = Create(7);
public static readonly UpdateQueueStatus Cancelled = Create(8);
public static readonly UpdateQueueStatus Downloading = Create(2);
public string Value { get; }
public UpdateQueueStatus(string value)
{
Value = value;
}
public static UpdateQueueStatus Parse(string value)
{
if (_mappings.TryGetValue(value, out var status))
{
return status;
}
var result = new UpdateQueueStatus(value);
while (true)
{
var currentMap = _mappings;
var newMap = new Dictionary<string, UpdateQueueStatus>(currentMap, StringComparer.OrdinalIgnoreCase);
newMap.TryAdd(value, result);
if (Interlocked.CompareExchange(ref _mappings, newMap, currentMap) == currentMap)
{
break;
}
}
return result;
}
private static UpdateQueueStatus Create(int number, [CallerMemberName] string? name = null)
{
var result = new UpdateQueueStatus(name ?? "None");
_mappings.TryAdd(number.ToString(), result);
_mappings.TryAdd(result.Value, result);
_intMappings.Add((result.Value, number));
return result;
}
}
// Test:
public class Test
{
[Fact]
public void Should_Be_Threadsafe()
{
var count = UpdateQueueStatus.GetMappings().Count;
var tasks = new List<Task>();
for (int i = 0; i < 100; i++)
{
var task = Task.Run(() =>
{
for (int j = 0; j < 100; j++)
{
UpdateQueueStatus.Parse("value" + j);
}
});
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
//Console.WriteLine("Number of keys in the dictionary: " + UpdateQueueStatus.GetMappings());
Assert.Equal(count + 100, UpdateQueueStatus.GetMappings().Count);
}
}