Skip to content

Commit 0a6f6db

Browse files
authored
ConcurrentDictionary<TKey, TValue> F# snippets (dotnet#8855)
1 parent c886a03 commit 0a6f6db

File tree

5 files changed

+180
-0
lines changed

5 files changed

+180
-0
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net7.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<Compile Include="program.fs" />
9+
</ItemGroup>
10+
</Project>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//<snippet1>
2+
open System
3+
open System.Collections.Concurrent
4+
5+
// Demonstrates:
6+
// ConcurrentDictionary<TKey, TValue> ctor(concurrencyLevel, initialCapacity)
7+
// ConcurrentDictionary<TKey, TValue>[TKey]
8+
9+
// We know how many items we want to insert into the ConcurrentDictionary.
10+
// So set the initial capacity to some prime number above that, to ensure that
11+
// the ConcurrentDictionary does not need to be resized while initializing it.
12+
let HIGHNUMBER = 64
13+
let initialCapacity = 101
14+
15+
// The higher the concurrencyLevel, the higher the theoretical number of operations
16+
// that could be performed concurrently on the ConcurrentDictionary. However, global
17+
// operations like resizing the dictionary take longer as the concurrencyLevel rises.
18+
// For the purposes of this example, we'll compromise at numCores * 2.
19+
let numProcs = Environment.ProcessorCount
20+
let concurrencyLevel = numProcs * 2
21+
22+
// Construct the dictionary with the desired concurrencyLevel and initialCapacity
23+
let cd = ConcurrentDictionary<int, int>(concurrencyLevel, initialCapacity)
24+
25+
// Initialize the dictionary
26+
for i = 1 to HIGHNUMBER do
27+
cd[i] <- i * i
28+
29+
printfn $"The square of 23 is {cd[23]} (should be {23 * 23})"
30+
31+
// Now iterate through, adding one to the end of the list. Existing items should be updated to be divided by their
32+
// key and a new item will be added that is the square of its key.
33+
for i = 1 to HIGHNUMBER + 1 do
34+
cd.AddOrUpdate(i, i * i, (fun k v -> v / i)) |> ignore
35+
36+
printfn $"The square root of 529 is {cd[23]} (should be {529 / 23})"
37+
printfn $"The square of 65 is {cd[HIGHNUMBER + 1]} (should be {(HIGHNUMBER + 1) * (HIGHNUMBER + 1)})"
38+
//</snippet1>
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
open System
2+
open System.Collections.Concurrent
3+
open System.Threading.Tasks
4+
//<snippet1>
5+
// Demonstrates:
6+
// ConcurrentDictionary<TKey, TValue> ctor(concurrencyLevel, initialCapacity)
7+
// ConcurrentDictionary<TKey, TValue>[TKey]
8+
9+
// We know how many items we want to insert into the ConcurrentDictionary.
10+
// So set the initial capacity to some prime number above that, to ensure that
11+
// the ConcurrentDictionary does not need to be resized while initializing it.
12+
let NUMITEMS = 64
13+
let initialCapacity = 101
14+
15+
// The higher the concurrencyLevel, the higher the theoretical number of operations
16+
// that could be performed concurrently on the ConcurrentDictionary. However, global
17+
// operations like resizing the dictionary take longer as the concurrencyLevel rises.
18+
// For the purposes of this example, we'll compromise at numCores * 2.
19+
let numProcs = Environment.ProcessorCount
20+
let concurrencyLevel = numProcs * 2
21+
22+
// Construct the dictionary with the desired concurrencyLevel and initialCapacity
23+
let cd = ConcurrentDictionary<int, int>(concurrencyLevel, initialCapacity)
24+
25+
// Initialize the dictionary
26+
for i = 0 to NUMITEMS - 1 do
27+
cd[i] <- i * i
28+
29+
printfn $"The square of 23 is {cd[23]} (should be {23 * 23})"
30+
//</snippet1>
31+
32+
do
33+
//<snippet2>
34+
// Demonstrates:
35+
// ConcurrentDictionary<TKey, TValue>.TryAdd()
36+
// ConcurrentDictionary<TKey, TValue>.TryUpdate()
37+
// ConcurrentDictionary<TKey, TValue>.TryRemove()
38+
39+
let mutable numFailures = 0 // for bookkeeping
40+
41+
// Construct an empty dictionary
42+
let cd = ConcurrentDictionary<int, string>()
43+
44+
// This should work
45+
if cd.TryAdd(1, "one") |> not then
46+
printfn "CD.TryAdd() failed when it should have succeeded"
47+
numFailures <- numFailures + 1
48+
49+
// This shouldn't work -- key 1 is already in use
50+
if cd.TryAdd(1, "uno") then
51+
printfn "CD.TryAdd() succeeded when it should have failed"
52+
numFailures <- numFailures + 1
53+
54+
// Now change the value for key 1 from "one" to "uno" -- should work
55+
if cd.TryUpdate(1, "uno", "one") |> not then
56+
printfn "CD.TryUpdate() failed when it should have succeeded"
57+
numFailures <- numFailures + 1
58+
59+
// Try to change the value for key 1 from "eine" to "one"
60+
// -- this shouldn't work, because the current value isn't "eine"
61+
if cd.TryUpdate(1, "one", "eine") then
62+
printfn "CD.TryUpdate() succeeded when it should have failed"
63+
numFailures <- numFailures + 1
64+
65+
// Remove key/value for key 1. Should work.
66+
let mutable value1 = ""
67+
68+
if cd.TryRemove(1, &value1) |> not then
69+
printfn "CD.TryRemove() failed when it should have succeeded"
70+
numFailures <- numFailures + 1
71+
72+
// Remove key/value for key 1. Shouldn't work, because I already removed it
73+
let mutable value2 = ""
74+
75+
if cd.TryRemove(1, &value2) then
76+
printfn "CD.TryRemove() succeeded when it should have failed"
77+
numFailures <- numFailures + 1
78+
79+
// If nothing went wrong, say so
80+
if numFailures = 0 then
81+
printfn " OK!"
82+
//</snippet2>
83+
84+
do
85+
//<snippet3>
86+
// Demonstrates:
87+
// ConcurrentDictionary<TKey, TValue>.AddOrUpdate()
88+
// ConcurrentDictionary<TKey, TValue>.GetOrAdd()
89+
// ConcurrentDictionary<TKey, TValue>[]
90+
91+
// Construct a ConcurrentDictionary
92+
let cd = ConcurrentDictionary<int, int>()
93+
94+
// Bombard the ConcurrentDictionary with 10000 competing AddOrUpdates
95+
Parallel.For(
96+
0,
97+
10000,
98+
fun i ->
99+
100+
// Initial call will set cd[1] = 1.
101+
// Ensuing calls will set cd[1] = cd[1] + 1
102+
cd.AddOrUpdate(1, 1, (fun key oldValue -> oldValue + 1)) |> ignore
103+
)
104+
|> ignore
105+
106+
printfn $"After 10000 AddOrUpdates, cd[1] = {cd[1]}, should be 10000"
107+
108+
// Should return 100, as key 2 is not yet in the dictionary
109+
let value = cd.GetOrAdd(2, (fun key -> 100))
110+
printfn $"After initial GetOrAdd, cd[2] = {value} (should be 100)"
111+
112+
// Should return 100, as key 2 is already set to that value2
113+
let value2 = cd.GetOrAdd(2, 10000)
114+
printfn $"After second GetOrAdd, cd[2] = {value2} (should be 100)"
115+
//</snippet3>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net7.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<Compile Include="concdictionary.fs" />
9+
</ItemGroup>
10+
</Project>

xml/System.Collections.Concurrent/ConcurrentDictionary`2.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125
The following example shows how to construct a <xref:System.Collections.Concurrent.ConcurrentDictionary%602> object.
126126
127127
:::code language="csharp" source="~/snippets/csharp/System.Collections.Concurrent/ConcurrentDictionaryTKey,TValue/Overview/concdictionary.cs" id="Snippet1":::
128+
:::code language="fsharp" source="~/snippets/fsharp/System.Collections.Concurrent/ConcurrentDictionaryTKey,TValue/Overview/concdictionary.fs" id="Snippet1":::
128129
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.collections.concurrent.concurrentdictionary/vb/concdictionary.vb" id="Snippet1":::
129130
130131
]]></format>
@@ -478,6 +479,7 @@
478479
The following example shows how to call the <xref:System.Collections.Concurrent.ConcurrentDictionary%602.AddOrUpdate%2A> method:
479480
480481
:::code language="csharp" source="~/snippets/csharp/System.Collections.Concurrent/ConcurrentDictionaryTKey,TValue/Overview/concdictionary.cs" id="Snippet3":::
482+
:::code language="fsharp" source="~/snippets/fsharp/System.Collections.Concurrent/ConcurrentDictionaryTKey,TValue/Overview/concdictionary.fs" id="Snippet3":::
481483
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.collections.concurrent.concurrentdictionary/vb/concdictionary.vb" id="Snippet3":::
482484
483485
]]></format>
@@ -594,6 +596,7 @@
594596
The following code example shows how to initialize an <xref:System.Collections.Concurrent.ConcurrentDictionary%602> and how to use the AddOrUpdate method to add an additional item to the collection, and update the existing items.
595597
596598
:::code language="csharp" source="~/snippets/csharp/System.Collections.Concurrent/ConcurrentDictionaryTKey,TValue/AddOrUpdate/program.cs" id="Snippet1":::
599+
:::code language="fsharp" source="~/snippets/fsharp/System.Collections.Concurrent/ConcurrentDictionaryTKey,TValue/AddOrUpdate/program.fs" id="Snippet1":::
597600
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.collections.concurrentcoladdupdate/vb/module1.vb" id="Snippet1":::
598601
599602
## Remarks
@@ -931,6 +934,7 @@
931934
The following example shows how to call the <xref:System.Collections.Concurrent.ConcurrentDictionary%602.GetOrAdd%2A> method:
932935
933936
:::code language="csharp" source="~/snippets/csharp/System.Collections.Concurrent/ConcurrentDictionaryTKey,TValue/Overview/concdictionary.cs" id="Snippet3":::
937+
:::code language="fsharp" source="~/snippets/fsharp/System.Collections.Concurrent/ConcurrentDictionaryTKey,TValue/Overview/concdictionary.fs" id="Snippet3":::
934938
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.collections.concurrent.concurrentdictionary/vb/concdictionary.vb" id="Snippet3":::
935939
936940
]]></format>
@@ -2430,6 +2434,7 @@ This member is an explicit interface member implementation. It can be used only
24302434
The following example shows how to call the <xref:System.Collections.Concurrent.ConcurrentDictionary%602.TryAdd%2A?displayProperty=nameWithType> method:
24312435
24322436
:::code language="csharp" source="~/snippets/csharp/System.Collections.Concurrent/ConcurrentDictionaryTKey,TValue/Overview/concdictionary.cs" id="Snippet2":::
2437+
:::code language="fsharp" source="~/snippets/fsharp/System.Collections.Concurrent/ConcurrentDictionaryTKey,TValue/Overview/concdictionary.fs" id="Snippet2":::
24332438
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.collections.concurrent.concurrentdictionary/vb/concdictionary.vb" id="Snippet2":::
24342439
24352440
]]></format>
@@ -2600,6 +2605,7 @@ The key is compared using the dictionary's comparer (or the default comparer for
26002605
The following example shows how to call the <xref:System.Collections.Concurrent.ConcurrentDictionary%602.TryRemove%2A?displayProperty=nameWithType> method:
26012606
26022607
:::code language="csharp" source="~/snippets/csharp/System.Collections.Concurrent/ConcurrentDictionaryTKey,TValue/Overview/concdictionary.cs" id="Snippet2":::
2608+
:::code language="fsharp" source="~/snippets/fsharp/System.Collections.Concurrent/ConcurrentDictionaryTKey,TValue/Overview/concdictionary.fs" id="Snippet2":::
26032609
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.collections.concurrent.concurrentdictionary/vb/concdictionary.vb" id="Snippet2":::
26042610
26052611
]]></format>
@@ -2660,6 +2666,7 @@ The key is compared using the dictionary's comparer (or the default comparer for
26602666
The following example shows how to call the <xref:System.Collections.Concurrent.ConcurrentDictionary%602.TryUpdate%2A> method:
26612667
26622668
:::code language="csharp" source="~/snippets/csharp/System.Collections.Concurrent/ConcurrentDictionaryTKey,TValue/Overview/concdictionary.cs" id="Snippet2":::
2669+
:::code language="fsharp" source="~/snippets/fsharp/System.Collections.Concurrent/ConcurrentDictionaryTKey,TValue/Overview/concdictionary.fs" id="Snippet2":::
26632670
:::code language="vb" source="~/snippets/visualbasic/VS_Snippets_CLR_System/system.collections.concurrent.concurrentdictionary/vb/concdictionary.vb" id="Snippet2":::
26642671
26652672
]]></format>

0 commit comments

Comments
 (0)