public static void Concat_String_ConcurrencySafe()
{
var inputs = new string[2] { "abc", "def" };
var cts = new CancellationTokenSource();
using (var b = new Barrier(2))
{
// String.Concat(string[]) has a slow path that handles the case where the
// input array is mutated concurrently. Queue two tasks, one that repeatedly
// does concats and the other that mutates the array concurrently. This isn't
// guaranteed to trigger the special case, but it typically does.
Task.WaitAll(
Task.Run(() =>
{
b.SignalAndWait();
while (!cts.IsCancellationRequested)
{
string result = string.Concat(inputs);
Assert.True(result == "abcdef" || result == "abc" || result == "def" || result == "", $"result == {result}");
}
}),
Task.Run(() =>
{
b.SignalAndWait();
try
{
for (int iter = 0; iter < 100000000; iter++)
{
Volatile.Write(ref inputs[0], null);
Volatile.Write(ref inputs[1], null);
Volatile.Write(ref inputs[0], "abc");
Volatile.Write(ref inputs[1], "def");
}
}
finally
{
cts.Cancel();
}
}));
}
}