コード例 #1
0
        public async Task CallbackIsCalled()
        {
            int attemptCount = 100;

            for (int i = 0; i < attemptCount; i++)
            {
                await checkConcurrentGetOrAdd();
            }

            async Task checkConcurrentGetOrAdd()
            {
                var         cd              = new ConcurrentDictionary <int, int>();
                const int   key             = 42;
                bool        factoryIsCalled = false;
                Task <bool> addTask         = Task.Run(() => cd.TryAdd(key, 1));
                Task <int>  addOrUpdateTask = Task.Run(
                    () =>
                {
                    return(ConcurrentDictionaryExtensions.GetOrAdd(
                               cd,
                               key,
                               (k, state) =>
                    {
                        factoryIsCalled = true;
                        return 2;
                    },
                               factoryArgument: string.Empty));
                });

                await Task.WhenAll(addTask, addOrUpdateTask);

                var addOrUpdateResult = await addOrUpdateTask;

                if (factoryIsCalled)
                {
                    // If factory was called, the result can still be obtained from the TryAdd call
                    addOrUpdateResult.Should().BeInRange(1, 2);
                }
                else
                {
                    addOrUpdateResult.Should().Be(1);
                }

                // Printing the outcome just for debugging purposes.
                if (factoryIsCalled && addOrUpdateResult == 1)
                {
                    Output.WriteLine("Factory was called, but the race was lost.");
                }

                if (factoryIsCalled && addOrUpdateResult == 2)
                {
                    Output.WriteLine("Factory was called, and the race was won.");
                }

                if (!factoryIsCalled)
                {
                    Output.WriteLine("Factory was not called");
                }
            }
        }
コード例 #2
0
        public void AddOrGetReturnsFirstResult()
        {
            var cd     = new ConcurrentDictionary <int, int>();
            var result = ConcurrentDictionaryExtensions.GetOrAdd(cd, 42,
                                                                 (key, args) =>
            {
                return(42);
            }, factoryArgument: string.Empty);

            result.Should().Be(42);
        }