public static void TestClear() { var dictionary = new NonBlocking.ConcurrentDictionary <int, int>(); for (int i = 0; i < 10; i++) { dictionary.TryAdd(i, i); } Assert.Equal(10, dictionary.Count); dictionary.Clear(); Assert.Equal(0, dictionary.Count); int item; Assert.False(dictionary.TryRemove(1, out item), "TestClear: FAILED. TryRemove succeeded after Clear"); Assert.True(dictionary.IsEmpty, "TestClear: FAILED. IsEmpty returned false after Clear"); }
public static void TestClear() { var dictionary = new NonBlocking.ConcurrentDictionary <int, int>(); for (int i = 0; i < 10; i++) { dictionary.TryAdd(i, i); } Assert.Equal(10, dictionary.Count); dictionary.Clear(); #pragma warning disable xUnit2013 // Do not use equality check to check for collection size. Assert.Equal(0, dictionary.Count); #pragma warning restore xUnit2013 // Do not use equality check to check for collection size. int item; Assert.False(dictionary.TryRemove(1, out item), "TestClear: FAILED. TryRemove succeeded after Clear"); Assert.True(dictionary.IsEmpty, "TestClear: FAILED. IsEmpty returned false after Clear"); }
public static void TestTryUpdate() { var dictionary = new NonBlocking.ConcurrentDictionary <string, int>(); Assert.Throws <ArgumentNullException>( () => dictionary.TryUpdate(null, 0, 0)); // "TestTryUpdate: FAILED. TryUpdate didn't throw ANE when null key is passed"); for (int i = 0; i < 10; i++) { dictionary.TryAdd(i.ToString(), i); } for (int i = 0; i < 10; i++) { Assert.True(dictionary.TryUpdate(i.ToString(), i + 1, i), "TestTryUpdate: FAILED. TryUpdate failed!"); Assert.Equal(i + 1, dictionary[i.ToString()]); } //test TryUpdate concurrently dictionary.Clear(); for (int i = 0; i < 1000; i++) { dictionary.TryAdd(i.ToString(), i); } var mres = new ManualResetEventSlim(); Task[] tasks = new Task[10]; ThreadLocal <ThreadData> updatedKeys = new ThreadLocal <ThreadData>(true); for (int i = 0; i < tasks.Length; i++) { // We are creating the Task using TaskCreationOptions.LongRunning because... // there is no guarantee that the Task will be created on another thread. // There is also no guarantee that using this TaskCreationOption will force // it to be run on another thread. tasks[i] = Task.Factory.StartNew((obj) => { mres.Wait(); int index = (((int)obj) + 1) + 1000; updatedKeys.Value = new ThreadData(); updatedKeys.Value.ThreadIndex = index; for (int j = 0; j < dictionary.Count; j++) { if (dictionary.TryUpdate(j.ToString(), index, j)) { if (dictionary[j.ToString()] != index) { updatedKeys.Value.Succeeded = false; return; } updatedKeys.Value.Keys.Add(j.ToString()); } } }, i, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); } mres.Set(); Task.WaitAll(tasks); int numberSucceeded = 0; int totalKeysUpdated = 0; foreach (var threadData in updatedKeys.Values) { totalKeysUpdated += threadData.Keys.Count; if (threadData.Succeeded) { numberSucceeded++; } } Assert.True(numberSucceeded == tasks.Length, "One or more threads failed!"); Assert.True(totalKeysUpdated == dictionary.Count, String.Format("TestTryUpdate: FAILED. The updated keys count doesn't match the dictionary count, expected {0}, actual {1}", dictionary.Count, totalKeysUpdated)); foreach (var value in updatedKeys.Values) { for (int i = 0; i < value.Keys.Count; i++) { Assert.True(dictionary[value.Keys[i]] == value.ThreadIndex, String.Format("TestTryUpdate: FAILED. The updated value doesn't match the thread index, expected {0} actual {1}", value.ThreadIndex, dictionary[value.Keys[i]])); } } //test TryUpdate with non atomic values (intPtr > 8) var dict = new NonBlocking.ConcurrentDictionary <int, Struct16>(); dict.TryAdd(1, new Struct16(1, -1)); Assert.True(dict.TryUpdate(1, new Struct16(2, -2), new Struct16(1, -1)), "TestTryUpdate: FAILED. TryUpdate failed for non atomic values ( > 8 bytes)"); }