public void should_synchronize_initialization() { // While it's possible for multiple initializations to occur, // the framework will attempt to minimize duplicate initialization // by sychronizing subsequent threads after the first initialization // has begun. // Each time the cache is initialized the // value of this object will be incremented // after a simulated delay. var value = new IncrementingCachedObject(); var variable = GetBuilderOfLong() .WithKey(GenerateRandomKey()) .InitializeWith(value.Increment) .TimeoutAfter(10.Seconds()) .Create(); // Start the new initialization var initial = new Task <long>(() => variable.Value); initial.Start(); // Introduce a small delay to ensure the initial thread has time to start. Thread.Sleep(1000); // Simulate additional threads requesting the same resource. var competingThreads = new[] { Task.Factory.StartNew(() => variable.Value), Task.Factory.StartNew(() => variable.Value), Task.Factory.StartNew(() => variable.Value), Task.Factory.StartNew(() => variable.Value), Task.Factory.StartNew(() => variable.Value) }; // This is the result of the first initialization var result = initial.Result; // All competing initializations should have the same value. foreach (var task in competingThreads) { task.Result.Should().Be(result); } }
public void should_synchronize_initialization() { // While it's possible for multiple initializations to occur, // the framework will attempt to minimize duplicate initialization // by sychronizing subsequent threads after the first initialization // has begun. // Each time the cache is initialized the // value of this object will be incremented // after a simulated delay. var value = new IncrementingCachedObject(); var variable = GetBuilderOfLong() .WithKey(GenerateRandomKey()) .InitializeWith(value.Increment) .TimeoutAfter(10.Seconds()) .Create(); // Start the new initialization var initial = new Task<long>(() => variable.Value); initial.Start(); // Introduce a small delay to ensure the initial thread has time to start. Thread.Sleep(1000); // Simulate additional threads requesting the same resource. var competingThreads = new[] { Task.Factory.StartNew(() => variable.Value), Task.Factory.StartNew(() => variable.Value), Task.Factory.StartNew(() => variable.Value), Task.Factory.StartNew(() => variable.Value), Task.Factory.StartNew(() => variable.Value) }; // This is the result of the first initialization var result = initial.Result; // All competing initializations should have the same value. foreach (var task in competingThreads) { task.Result.Should().Be(result); } }