|
450 | 450 | <param name="addValueFactory">The function used to generate a value for an absent key</param> |
451 | 451 | <param name="updateValueFactory">The function used to generate a new value for an existing key based on the key's existing value</param> |
452 | 452 | <summary>Uses the specified functions to add a key/value pair to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> if the key does not already exist, or to update a key/value pair in the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> if the key already exists.</summary> |
453 | | - <returns>The new value for the key. This will be either be the result of addValueFactory (if the key was absent) or the result of updateValueFactory (if the key was present).</returns> |
| 453 | + <returns>The new value for the key. This will be either be the result of <c>addValueFactory</c> (if the key was absent) or the result of <c>updateValueFactory</c> (if the key was present).</returns> |
454 | 454 | <remarks> |
455 | 455 | <format type="text/markdown"><![CDATA[ |
456 | 456 | |
457 | 457 | ## Remarks |
458 | 458 | If you call <xref:System.Collections.Concurrent.ConcurrentDictionary%602.AddOrUpdate%2A> simultaneously on different threads, `addValueFactory` may be called multiple times, but its key/value pair might not be added to the dictionary for every call. |
| 459 | +
|
| 460 | + For modifications and write operations to the dictionary, <xref:System.Collections.Concurrent.ConcurrentDictionary%602> uses fine-grained locking to ensure thread safety. (Read operations on the dictionary are performed in a lock-free manner.) However, the `addValueFactory` and `updateValueFactory` delegates are called outside the locks to avoid the problems that can arise from executing unknown code under a lock. Therefore, <xref:System.Collections.Concurrent.ConcurrentDictionary%602.AddOrUpdate%2A> is not atomic with regards to all other operations on the <xref:System.Collections.Concurrent.ConcurrentDictionary%602> class. |
459 | 461 | |
460 | 462 | ]]></format> |
461 | 463 | </remarks> |
|
502 | 504 | <param name="addValue">The value to be added for an absent key</param> |
503 | 505 | <param name="updateValueFactory">The function used to generate a new value for an existing key based on the key's existing value</param> |
504 | 506 | <summary>Adds a key/value pair to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> if the key does not already exist, or updates a key/value pair in the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> by using the specified function if the key already exists.</summary> |
505 | | - <returns>The new value for the key. This will be either be addValue (if the key was absent) or the result of updateValueFactory (if the key was present).</returns> |
| 507 | + <returns>The new value for the key. This will be either be <c>addValue</c> (if the key was absent) or the result of <c>updateValueFactory</c> (if the key was present).</returns> |
506 | 508 | <remarks> |
507 | 509 | <format type="text/markdown"><] |
513 | 515 | [!code-vb[System.Collections.ConcurrentColAddUpdate#1](~/samples/snippets/visualbasic/VS_Snippets_CLR_System/system.collections.concurrentcoladdupdate/vb/module1.vb#1)] |
| 516 | +
|
| 517 | +## Remarks |
| 518 | + For modifications and write operations to the dictionary, <xref:System.Collections.Concurrent.ConcurrentDictionary%602> uses fine-grained locking to ensure thread safety. (Read operations on the dictionary are performed in a lock-free manner.) However, the `updateValueFactory` delegate is called outside the locks to avoid the problems that can arise from executing unknown code under a lock. Therefore, <xref:System.Collections.Concurrent.ConcurrentDictionary%602.AddOrUpdate%2A> is not atomic with regards to all other operations on the <xref:System.Collections.Concurrent.ConcurrentDictionary%602> class. |
514 | 519 | |
515 | 520 | ]]></format> |
516 | 521 | </remarks> |
|
553 | 558 | <Parameter Name="factoryArgument" Type="TArg" /> |
554 | 559 | </Parameters> |
555 | 560 | <Docs> |
556 | | - <typeparam name="TArg">The type of the keys in this <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /></typeparam> |
| 561 | + <typeparam name="TArg">The type of an argument to pass into <c>addValueFactory</c> and <c>updateValueFactory</c>.</typeparam> |
557 | 562 | <param name="key">The key to be added or whose value should be updated.</param> |
558 | 563 | <param name="addValueFactory">The function used to generate a value for an absent key.</param> |
559 | 564 | <param name="updateValueFactory">The function used to generate a new value for an existing key based on the key's existing value.</param> |
560 | 565 | <param name="factoryArgument">An argument to pass into <c>addValueFactory</c> and <c>updateValueFactory</c>.</param> |
561 | | - <summary>Adds a key/value pair to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> if the key does not already exist, or updates a key/value pair in the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> if the key already exists.</summary> |
562 | | - <returns>The new value for the key. This will be either be the result of addValueFactory (if the key was absent) or the result of updateValueFactory (if the key was present).</returns> |
563 | | - <remarks>To be added.</remarks> |
| 566 | + <summary>Uses the specified functions and argument to add a key/value pair to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> if the key does not already exist, or to update a key/value pair in the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> if the key already exists.</summary> |
| 567 | + <returns>The new value for the key. This will be either be the result of <c>addValueFactory</c> (if the key was absent) or the result of <c>updateValueFactory</c> (if the key was present).</returns> |
| 568 | + <remarks> |
| 569 | + <format type="text/markdown"><![CDATA[ |
| 570 | + |
| 571 | +## Remarks |
| 572 | + If you call <xref:System.Collections.Concurrent.ConcurrentDictionary%602.AddOrUpdate%2A> simultaneously on different threads, `addValueFactory` may be called multiple times, but its key/value pair might not be added to the dictionary for every call. |
| 573 | +
|
| 574 | + For modifications and write operations to the dictionary, <xref:System.Collections.Concurrent.ConcurrentDictionary%602> uses fine-grained locking to ensure thread safety. (Read operations on the dictionary are performed in a lock-free manner.) However, the `addValueFactory` and `updateValueFactory` delegates are called outside the locks to avoid the problems that can arise from executing unknown code under a lock. Therefore, <xref:System.Collections.Concurrent.ConcurrentDictionary%602.AddOrUpdate%2A> is not atomic with regards to all other operations on the <xref:System.Collections.Concurrent.ConcurrentDictionary%602> class. |
| 575 | + |
| 576 | + ]]></format> |
| 577 | + </remarks> |
564 | 578 | <exception cref="T:System.ArgumentNullException"> |
565 | 579 | <paramref name="key" />, <paramref name="addValueFactory" />, or <paramref name="updateValueFactory" /> is a null reference (Nothing in Visual Basic).</exception> |
566 | 580 | </Docs> |
|
757 | 771 | <AssemblyVersion>4.0.10.0</AssemblyVersion> |
758 | 772 | </AssemblyInfo> |
759 | 773 | <Docs> |
760 | | - <summary>Adds a key/value pair to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> if the key does not already exist.</summary> |
| 774 | + <summary>Adds a key/value pair to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> if the key does not already exist, or returns the existing value if the key exists.</summary> |
761 | 775 | <remarks> |
762 | 776 | <format type="text/markdown"><![CDATA[ |
763 | 777 | |
|
812 | 826 | <format type="text/markdown"><![CDATA[ |
813 | 827 | |
814 | 828 | ## Remarks |
| 829 | + For modifications and write operations to the dictionary, <xref:System.Collections.Concurrent.ConcurrentDictionary%602> uses fine-grained locking to ensure thread safety. (Read operations on the dictionary are performed in a lock-free manner.) However, the `valueFactory` delegate is called outside the locks to avoid the problems that can arise from executing unknown code under a lock. Therefore, <xref:System.Collections.Concurrent.ConcurrentDictionary%602.GetOrAdd%2A> is not atomic with regards to all other operations on the <xref:System.Collections.Concurrent.ConcurrentDictionary%602> class. |
| 830 | +
|
815 | 831 | Since a key/value can be inserted by another thread while `valueFactory` is generating a value, you cannot trust that just because `valueFactory` executed, its produced value will be inserted into the dictionary and returned. If you call <xref:System.Collections.Concurrent.ConcurrentDictionary%602.GetOrAdd%2A> simultaneously on different threads, `valueFactory` may be called multiple times, but only one key/value pair will be added to the dictionary. |
816 | 832 | |
817 | 833 | The return value depends on the presence of the key in the dictionary and whether a key/value is inserted by another thread after <xref:System.Collections.Concurrent.ConcurrentDictionary%602.GetOrAdd%2A> is called but before `valueFactory` generates a value: |
|
864 | 880 | <Docs> |
865 | 881 | <param name="key">The key of the element to add.</param> |
866 | 882 | <param name="value">The value to be added, if the key does not already exist.</param> |
867 | | - <summary>Adds a key/value pair to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> if the key does not already exist.</summary> |
| 883 | + <summary>Adds a key/value pair to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> if the key does not already exist, or returns the existing value if the key exists.</summary> |
868 | 884 | <returns>The value for the key. This will be either the existing value for the key if the key is already in the dictionary, or the new value if the key was not in the dictionary.</returns> |
869 | 885 | <remarks>To be added.</remarks> |
870 | 886 | <exception cref="T:System.ArgumentNullException"> |
|
905 | 921 | <Parameter Name="factoryArgument" Type="TArg" /> |
906 | 922 | </Parameters> |
907 | 923 | <Docs> |
908 | | - <typeparam name="TArg">The type of the keys in this <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /></typeparam> |
| 924 | + <typeparam name="TArg">The type of an argument to pass into <c>valueFactory</c>.</typeparam> |
909 | 925 | <param name="key">The key of the element to add.</param> |
910 | 926 | <param name="valueFactory">The function used to generate a value for the key.</param> |
911 | | - <param name="factoryArgument">An argument value to pass into <c>name</c>.</param> |
912 | | - <summary>Adds a key/value pair to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> if the key does not already exist.</summary> |
913 | | - <returns>The value for the key. This will be either the existing value for the key if the key is already in the dictionary, or the new value for the key as returned by <paramref name="valueFactory" /> if the key was not in the dictionary.</returns> |
914 | | - <remarks>To be added.</remarks> |
| 927 | + <param name="factoryArgument">An argument value to pass into <c>valueFactory</c>.</param> |
| 928 | + <summary>Adds a key/value pair to the <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2" /> by using the specified function and an argument if the key does not already exist, or returns the existing value if the key exists.</summary> |
| 929 | + <returns>The value for the key. This will be either the existing value for the key if the key is already in the dictionary, or the new value if the key was not in the dictionary.</returns> |
| 930 | + <remarks> |
| 931 | + <format type="text/markdown"><![CDATA[ |
| 932 | + |
| 933 | +## Remarks |
| 934 | + For modifications and write operations to the dictionary, <xref:System.Collections.Concurrent.ConcurrentDictionary%602> uses fine-grained locking to ensure thread safety. (Read operations on the dictionary are performed in a lock-free manner.) However, the `valueFactory` delegate is called outside the locks to avoid the problems that can arise from executing unknown code under a lock. Therefore, <xref:System.Collections.Concurrent.ConcurrentDictionary%602.GetOrAdd%2A> is not atomic with regards to all other operations on the <xref:System.Collections.Concurrent.ConcurrentDictionary%602> class. |
| 935 | +
|
| 936 | + Since a key/value can be inserted by another thread while `valueFactory` is generating a value, you cannot trust that just because `valueFactory` executed, its produced value will be inserted into the dictionary and returned. If you call <xref:System.Collections.Concurrent.ConcurrentDictionary%602.GetOrAdd%2A> simultaneously on different threads, `valueFactory` may be called multiple times, but only one key/value pair will be added to the dictionary. |
| 937 | + |
| 938 | + The return value depends on the presence of the key in the dictionary and whether a key/value is inserted by another thread after <xref:System.Collections.Concurrent.ConcurrentDictionary%602.GetOrAdd%2A> is called but before `valueFactory` generates a value: |
| 939 | +
|
| 940 | + | Scenario | Return value | |
| 941 | + | -------- | ------------ | |
| 942 | + | The key is already in the dictionary. | The existing value is returned. | |
| 943 | + | The key is not in the dictionary. `valueFactory` generates a value. On rechecking for the key, no key is found. | The key/value is inserted into the dictionary, and the value is returned. | |
| 944 | + | The key is not in the dictionary. `valueFactory` generates a value. While `valueFactory` is generating the value, a different thread inserts a value for the key. After `valueFactory` executes and upon rechecking for the key, the key inserted by the other thread is found. | The value inserted by the other thread is returned. | |
| 945 | + |
| 946 | + ]]></format> |
| 947 | + </remarks> |
915 | 948 | </Docs> |
916 | 949 | </Member> |
917 | 950 | <Member MemberName="IsEmpty"> |
|
0 commit comments