Skip to content

Commit 2ef9a4c

Browse files
authored
System.Threading.Tasks.Task F# snippets (#8870)
* Task F# snippets * fix complication errors
1 parent 55aaa5d commit 2ef9a4c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1956
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module Run11
2+
// <Snippet11>
3+
open System.Threading
4+
open System.Threading.Tasks
5+
6+
let showThreadInfo s =
7+
printfn $"%s{s} thread ID: {Thread.CurrentThread.ManagedThreadId}"
8+
9+
showThreadInfo "Application"
10+
11+
let t = Task.Run(fun () -> showThreadInfo "Task")
12+
t.Wait()
13+
14+
// The example displays the following output:
15+
// Application thread ID: 1
16+
// Task thread ID: 3
17+
// </Snippet11>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
module Run28
2+
// <Snippet28>
3+
open System
4+
open System.Collections.Generic
5+
open System.Threading
6+
open System.Threading.Tasks
7+
8+
let source = new CancellationTokenSource()
9+
let token = source.Token
10+
let mutable completedIterations = 0
11+
12+
let tasks =
13+
[| for _ = 0 to 19 do
14+
Task.Run(
15+
(fun () ->
16+
let mutable iterations = 0
17+
18+
for _ = 1 to 2000000 do
19+
token.ThrowIfCancellationRequested()
20+
iterations <- iterations + 1
21+
22+
Interlocked.Increment &completedIterations |> ignore
23+
24+
if completedIterations >= 10 then
25+
source.Cancel()
26+
27+
iterations),
28+
token
29+
) |]
30+
31+
printfn "Waiting for the first 10 tasks to complete...\n"
32+
33+
try
34+
tasks |> Seq.cast |> Array.ofSeq |> Task.WaitAll
35+
36+
with :? AggregateException ->
37+
printfn "Status of tasks:\n"
38+
printfn "%10s %20s %14s" "Task Id" "Status" "Iterations"
39+
40+
for t in tasks do
41+
if t.Status <> TaskStatus.Canceled then
42+
t.Result.ToString "N0"
43+
else
44+
"n/a"
45+
|> printfn "%10i %20O %14s" t.Id t.Status
46+
47+
// The example displays output like the following:
48+
// Status of tasks:
49+
//
50+
// Task Id Status Iterations
51+
// 1 RanToCompletion 2,000,000
52+
// 2 RanToCompletion 2,000,000
53+
// 3 RanToCompletion 2,000,000
54+
// 4 RanToCompletion 2,000,000
55+
// 5 RanToCompletion 2,000,000
56+
// 6 RanToCompletion 2,000,000
57+
// 7 RanToCompletion 2,000,000
58+
// 8 RanToCompletion 2,000,000
59+
// 9 RanToCompletion 2,000,000
60+
// 10 RanToCompletion 1,658,326
61+
// 11 RanToCompletion 1,988,506
62+
// 12 RanToCompletion 2,000,000
63+
// 13 RanToCompletion 1,942,246
64+
// 14 RanToCompletion 950,108
65+
// 15 RanToCompletion 1,837,832
66+
// 16 RanToCompletion 1,687,182
67+
// 17 RanToCompletion 194,548
68+
// 18 Canceled Not Started
69+
// 19 Canceled Not Started
70+
// 20 Canceled Not Started
71+
// </Snippet28>
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
module Run7
2+
// <Snippet7>
3+
open System
4+
open System.Collections.Generic
5+
open System.Threading
6+
open System.Threading.Tasks
7+
8+
let source = new CancellationTokenSource()
9+
let token = source.Token
10+
let mutable completedIterations = 0
11+
12+
let tasks =
13+
[| for _ = 0 to 19 do
14+
Task.Run(
15+
(fun () ->
16+
let mutable iterations = 0
17+
18+
for _ = 1 to 2000000 do
19+
token.ThrowIfCancellationRequested()
20+
iterations <- iterations + 1
21+
22+
Interlocked.Increment &completedIterations |> ignore
23+
24+
if completedIterations >= 10 then
25+
source.Cancel()
26+
27+
iterations),
28+
token
29+
)
30+
31+
|]
32+
33+
printfn "Waiting for the first 10 tasks to complete...\n"
34+
35+
try
36+
tasks |> Seq.cast |> Array.ofSeq |> Task.WaitAll
37+
with :? AggregateException ->
38+
printfn "Status of tasks:\n"
39+
printfn "%10s %20s %14s" "Task Id" "Status" "Iterations"
40+
41+
for t in tasks do
42+
if t.Status <> TaskStatus.Canceled then
43+
t.Result.ToString "N0"
44+
else
45+
"n/a"
46+
|> printfn "%10i %20O %14s" t.Id t.Status
47+
48+
49+
// The example displays output like the following:
50+
// Waiting for the first 10 tasks to complete...
51+
// Status of tasks:
52+
//
53+
// Task Id Status Iterations
54+
// 1 RanToCompletion 2,000,000
55+
// 2 RanToCompletion 2,000,000
56+
// 3 RanToCompletion 2,000,000
57+
// 4 RanToCompletion 2,000,000
58+
// 5 RanToCompletion 2,000,000
59+
// 6 RanToCompletion 2,000,000
60+
// 7 RanToCompletion 2,000,000
61+
// 8 RanToCompletion 2,000,000
62+
// 9 RanToCompletion 2,000,000
63+
// 10 Canceled n/a
64+
// 11 Canceled n/a
65+
// 12 Canceled n/a
66+
// 13 Canceled n/a
67+
// 14 Canceled n/a
68+
// 15 Canceled n/a
69+
// 16 RanToCompletion 2,000,000
70+
// 17 Canceled n/a
71+
// 18 Canceled n/a
72+
// 19 Canceled n/a
73+
// 20 Canceled n/a
74+
// </Snippet7>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module ctor1
2+
// <Snippet1>
3+
open System.Collections.Concurrent
4+
open System.IO
5+
open System.Threading.Tasks
6+
7+
let main =
8+
task {
9+
let list = ConcurrentBag<string>()
10+
let dirNames = [ "."; ".." ]
11+
let tasks = ResizeArray()
12+
13+
for dirName in dirNames do
14+
let t =
15+
new Task(fun () ->
16+
for path in Directory.GetFiles dirName do
17+
list.Add path)
18+
19+
tasks.Add t
20+
t.Start()
21+
22+
do! tasks.ToArray() |> Task.WhenAll
23+
24+
for t in tasks do
25+
printfn $"Task {t.Id} Status: {t.Status}"
26+
27+
printfn $"Number of files read: {list.Count}"
28+
}
29+
30+
// The example displays output like the following:
31+
// Task 1 Status: RanToCompletion
32+
// Task 2 Status: RanToCompletion
33+
// Number of files read: 23
34+
// </Snippet1>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net7.0</TargetFramework>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<Compile Include="ctor1.fs" />
8+
<Compile Include="run2.fs" />
9+
<Compile Include="run4.fs" />
10+
<Compile Include="startnew3.fs" />
11+
<Compile Include="Run11.fs" />
12+
<Compile Include="run6.fs" />
13+
<Compile Include="run41.fs" />
14+
<Compile Include="run31.fs" />
15+
<Compile Include="Run7.fs" />
16+
<Compile Include="Run28.fs" />
17+
</ItemGroup>
18+
</Project>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
module run2
2+
// Example for Task.Run(Action) method.
3+
4+
// <Snippet1>
5+
open System.Collections.Concurrent
6+
open System.IO
7+
open System.Threading.Tasks
8+
9+
let list = ConcurrentBag<string>()
10+
let dirNames = [ "."; ".." ]
11+
let tasks = ResizeArray()
12+
13+
for dirName in dirNames do
14+
let t =
15+
Task.Run(fun () ->
16+
for path in Directory.GetFiles dirName do
17+
list.Add path)
18+
19+
tasks.Add t
20+
21+
tasks.ToArray() |> Task.WaitAll
22+
23+
for t in tasks do
24+
printfn $"Task {t.Id} Status: {t.Status}"
25+
26+
printfn $"Number of files read: {list.Count}"
27+
28+
// The example displays output like the following:
29+
// Task 1 Status: RanToCompletion
30+
// Task 2 Status: RanToCompletion
31+
// Number of files read: 23
32+
// </Snippet1>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module run31
2+
// <Snippet2>
3+
open System
4+
open System.IO
5+
open System.Text.RegularExpressions
6+
open System.Threading.Tasks
7+
8+
let pattern = @"\p{P}*\s+"
9+
let titles = [| "Sister Carrie"; "The Financier" |]
10+
11+
let tasks =
12+
Array.map (fun title ->
13+
Task.Run(fun () ->
14+
// Create filename from title.
15+
let fn = title + ".txt"
16+
17+
if File.Exists fn then
18+
use sr = new StreamReader(fn)
19+
let input = sr.ReadToEndAsync().Result
20+
Regex.Matches(input, pattern).Count
21+
else
22+
0)) titles
23+
24+
tasks |> Seq.cast |> Array.ofSeq |> Task.WaitAll
25+
26+
printfn "Word Counts:\n"
27+
28+
for i = 0 to tasks.Length - 1 do
29+
printfn $"%s{titles.[i]}: %10d{tasks.[i].Result} words"
30+
31+
// The example displays the following output:
32+
// Sister Carrie: 159,374 words
33+
// The Financier: 196,362 words
34+
// </Snippet2>
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
module run4
2+
// Illustrates the Task.Run(Action, CancellationToken) overload.
3+
4+
// <Snippet4>
5+
open System
6+
open System.IO
7+
open System.Threading
8+
open System.Threading.Tasks
9+
10+
let main =
11+
task {
12+
use tokenSource = new CancellationTokenSource()
13+
let token = tokenSource.Token
14+
let files = ResizeArray()
15+
16+
let t =
17+
new Task(
18+
(fun () ->
19+
let dir = @"C:\Windows\System32\"
20+
let obj = obj ()
21+
22+
if Directory.Exists dir then
23+
Parallel.ForEach(
24+
Directory.GetFiles dir,
25+
fun f ->
26+
if token.IsCancellationRequested then
27+
token.ThrowIfCancellationRequested()
28+
29+
let fi = FileInfo f
30+
lock obj (fun () -> files.Add(fi.Name, fi.DirectoryName, fi.Length, fi.LastWriteTimeUtc))
31+
)
32+
|> ignore),
33+
token
34+
)
35+
36+
t.Start()
37+
tokenSource.Cancel()
38+
39+
try
40+
do! t
41+
printfn $"Retrieved information for {files.Count} files."
42+
43+
with :? AggregateException as e ->
44+
printfn "Exception messages:"
45+
46+
for ie in e.InnerExceptions do
47+
printfn $" {ie.GetType().Name}: {ie.Message}"
48+
49+
printfn $"Task status: {t.Status}"
50+
}
51+
52+
main.Wait()
53+
54+
// The example displays the following output:
55+
// Exception messages:
56+
// TaskCanceledException: A task was canceled.
57+
//
58+
// Task status: Canceled
59+
// </Snippet4>

0 commit comments

Comments
 (0)