Skip to content

Commit e77c6c5

Browse files
authored
System.Timers F# snippets (dotnet#8861)
1 parent 0a6f6db commit e77c6c5

File tree

15 files changed

+488
-0
lines changed

15 files changed

+488
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module AsyncHanderEx
2+
// <Snippet3>
3+
open System
4+
open System.Threading.Tasks
5+
open System.Timers
6+
7+
let handleTimer () =
8+
printfn "\nHandler not implemented..."
9+
raise (NotImplementedException()): Task
10+
11+
let timer = new Timer 1000
12+
timer.Elapsed.AddHandler(fun sender e -> task { do! handleTimer () } |> ignore)
13+
timer.Start()
14+
printf "Press any key to exit... "
15+
Console.ReadKey() |> ignore
16+
17+
// The example displays output like the following:
18+
// Press any key to exit...
19+
// Handler not implemented...
20+
//
21+
// Unhandled Exception: System.NotImplementedException: The method or operation is not implemented.
22+
// at Example.HandleTimer()
23+
// at Example.<<Main>b__0>d__2.MoveNext()
24+
// --- End of stack trace from previous location where exception was thrown ---
25+
// at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c__DisplayClass2.<ThrowAsync>b__5(Object state)
26+
// at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
27+
// at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
28+
// at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
29+
// at System.Threading.ThreadPoolWorkQueue.Dispatch()
30+
// </Snippet3>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<OutputType>Exe</OutputType>
4+
<TargetFramework>net7.0</TargetFramework>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<Compile Include="AsyncHandlerEx1.fs" />
8+
<Compile Include="timer1.fs" />
9+
<Compile Include="timer2a.fs" />
10+
</ItemGroup>
11+
</Project>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
module timer1
2+
3+
// <Snippet1>
4+
open System.Timers
5+
6+
let onTimedEvent source (e: ElapsedEventArgs) =
7+
printfn $"The Elapsed event was raised at {e.SignalTime}"
8+
9+
// Create a timer and set a two second interval.
10+
let aTimer = new Timer()
11+
aTimer.Interval <- 2000
12+
13+
// Hook up the Elapsed event for the timer.
14+
aTimer.Elapsed.AddHandler onTimedEvent
15+
16+
// Have the timer fire repeated events (true is the default)
17+
aTimer.AutoReset <- true
18+
19+
// Start the timer
20+
aTimer.Enabled <- true
21+
22+
printfn "Press the Enter key to exit the program at any time... "
23+
stdin.ReadLine() |> ignore
24+
25+
// The example displays output like the following:
26+
// Press the Enter key to exit the program at any time...
27+
// The Elapsed event was raised at 5/20/2015 8:48:58 PM
28+
// The Elapsed event was raised at 5/20/2015 8:49:00 PM
29+
// The Elapsed event was raised at 5/20/2015 8:49:02 PM
30+
// The Elapsed event was raised at 5/20/2015 8:49:04 PM
31+
// The Elapsed event was raised at 5/20/2015 8:49:06 PM
32+
// </Snippet1>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
module timer2a
2+
3+
// <Snippet2>
4+
open System
5+
open System.Timers
6+
7+
let onTimedEvent source (e: ElapsedEventArgs) =
8+
printfn $"""The Elapsed event was raised at {e.SignalTime.ToString "HH:mm:ss.fff"}"""
9+
10+
// Create a timer with a two second interval.
11+
let aTimer = new Timer 2000
12+
// Hook up the Elapsed event for the timer.
13+
aTimer.Elapsed.AddHandler onTimedEvent
14+
aTimer.AutoReset <- true
15+
aTimer.Enabled <- true
16+
17+
printfn "\nPress the Enter key to exit the application...\n"
18+
printfn $"""The application started at {DateTime.Now.ToString "HH:mm:ss.fff"}"""
19+
stdin.ReadLine() |> ignore
20+
aTimer.Stop()
21+
aTimer.Dispose()
22+
23+
printfn "Terminating the application..."
24+
25+
// The example displays output like the following:
26+
// Press the Enter key to exit the application...
27+
//
28+
// The application started at 09:40:29.068
29+
// The Elapsed event was raised at 09:40:31.084
30+
// The Elapsed event was raised at 09:40:33.100
31+
// The Elapsed event was raised at 09:40:35.100
32+
// The Elapsed event was raised at 09:40:37.116
33+
// The Elapsed event was raised at 09:40:39.116
34+
// The Elapsed event was raised at 09:40:41.117
35+
// The Elapsed event was raised at 09:40:43.132
36+
// The Elapsed event was raised at 09:40:45.133
37+
// The Elapsed event was raised at 09:40:47.148
38+
//
39+
// Terminating the application...
40+
// </Snippet2>
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="source.fs" />
9+
</ItemGroup>
10+
</Project>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// <Snippet1>
2+
// To avoid confusion with other Timer classes, this sample always uses the fully-qualified
3+
// name of System.Timers.Timer instead of a using statement for System.Timers.
4+
module Example
5+
6+
let mutable aTimer = new System.Timers.Timer()
7+
8+
let onTimedEvent source (e: System.Timers.ElapsedEventArgs) =
9+
printfn $"The Elapsed event was raised at {e.SignalTime}"
10+
11+
[<EntryPoint>]
12+
let main _ =
13+
// Normally, the timer is declared at the class level, so that it stays in scope as long as it
14+
// is needed. If the timer is declared in a long-running method, KeepAlive must be used to prevent
15+
// the JIT compiler from allowing aggressive garbage collection to occur before the method ends.
16+
// You can experiment with this by commenting out the class-level declaration and uncommenting
17+
// the declaration below then uncomment the GC.KeepAlive(aTimer) at the end of the method.
18+
//System.Timers.Timer aTimer
19+
20+
// Set a two second interval.
21+
aTimer.Interval <- 2000
22+
23+
// Alternate method: create a Timer with an interval argument to the constructor.
24+
//aTimer = new System.Timers.Timer(2000)
25+
26+
// Create a timer with a two second interval.
27+
aTimer <- new System.Timers.Timer(2000)
28+
29+
// Hook up the Elapsed event for the timer.
30+
aTimer.Elapsed.AddHandler onTimedEvent
31+
32+
// Have the timer fire repeated events (true is the default)
33+
aTimer.AutoReset <- true
34+
35+
// Start the timer
36+
aTimer.Enabled <- true
37+
38+
printfn "Press the Enter key to exit the program at any time... "
39+
stdin.ReadLine() |> ignore
40+
41+
// If the timer is declared in a long-running method, use KeepAlive to prevent garbage collection
42+
// from occurring before the method ends.
43+
//GC.KeepAlive(aTimer)
44+
0
45+
46+
// This example displays output like the following:
47+
// Press the Enter key to exit the program at any time...
48+
// The Elapsed event was raised at 5/20/2015 8:48:58 PM
49+
// The Elapsed event was raised at 5/20/2015 8:49:00 PM
50+
// The Elapsed event was raised at 5/20/2015 8:49:02 PM
51+
// The Elapsed event was raised at 5/20/2015 8:49:04 PM
52+
// The Elapsed event was raised at 5/20/2015 8:49:06 PM
53+
54+
// </Snippet1>
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="source.fs" />
9+
</ItemGroup>
10+
</Project>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// <Snippet1>
2+
open System.Threading
3+
open System.Timers
4+
5+
// Handle the Elapsed event.
6+
let onTimedEvent source e =
7+
printfn "Hello World!"
8+
9+
// Create a timer with a 1.5 second interval.
10+
let interval = 1500.
11+
let aTimer = new Timer(interval)
12+
13+
// Hook up the event handler for the Elapsed event.
14+
aTimer.Elapsed.AddHandler(ElapsedEventHandler onTimedEvent)
15+
16+
// Only raise the event the first time Interval elapses.
17+
aTimer.AutoReset <- false
18+
aTimer.Enabled <- true
19+
20+
// Ensure the event fires before the exit message appears.
21+
Thread.Sleep(interval * 2. |> int)
22+
printfn "Press the Enter key to exit the program."
23+
stdin.ReadLine() |> ignore
24+
25+
// This example displays the following output:
26+
// Hello World!
27+
// Press the Enter key to exit the program.
28+
// </Snippet1>
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="interval2.fs" />
9+
</ItemGroup>
10+
</Project>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// What is the resolution of the system clock?
2+
3+
// <Snippet1>
4+
open System
5+
open System.IO
6+
open System.Timers
7+
8+
let aTimer = new Timer 5
9+
let eventlog = ResizeArray()
10+
let mutable nEventsFired = 0
11+
let mutable previousTime = DateTime()
12+
13+
let onTimedEvent source (e: ElapsedEventArgs) =
14+
String.Format("Elapsed event at {0:HH':'mm':'ss.ffffff} ({1})", e.SignalTime, if nEventsFired = 0 then 0. else (e.SignalTime - previousTime).TotalMilliseconds)
15+
|> eventlog.Add
16+
nEventsFired <- nEventsFired + 1
17+
18+
previousTime <- e.SignalTime
19+
20+
if nEventsFired = 20 then
21+
printfn "No more events will fire..."
22+
aTimer.Enabled <- false
23+
24+
[<EntryPoint>]
25+
let main _ =
26+
use sr = new StreamWriter(@".\Interval.txt")
27+
// Create a timer with a five millisecond interval.
28+
aTimer.Elapsed.AddHandler onTimedEvent
29+
// Hook up the Elapsed event for the timer.
30+
aTimer.AutoReset <- true
31+
sr.WriteLine $"The timer should fire every {aTimer.Interval} milliseconds."
32+
aTimer.Enabled <- true
33+
34+
printfn "Press the Enter key to exit the program... "
35+
stdin.ReadLine() |> ignore
36+
for item in eventlog do
37+
sr.WriteLine item
38+
printfn "Terminating the application..."
39+
0
40+
41+
// The example writes output like the following to a file:
42+
// The timer should fire every 5 milliseconds.
43+
// Elapsed event at 08:42:49.370344 (0)
44+
// Elapsed event at 08:42:49.385345 (15.0015)
45+
// Elapsed event at 08:42:49.400347 (15.0015)
46+
// Elapsed event at 08:42:49.415348 (15.0015)
47+
// Elapsed event at 08:42:49.430350 (15.0015)
48+
// Elapsed event at 08:42:49.445351 (15.0015)
49+
// Elapsed event at 08:42:49.465353 (20.002)
50+
// Elapsed event at 08:42:49.480355 (15.0015)
51+
// Elapsed event at 08:42:49.495356 (15.0015)
52+
// Elapsed event at 08:42:49.510358 (15.0015)
53+
// Elapsed event at 08:42:49.525359 (15.0015)
54+
// Elapsed event at 08:42:49.540361 (15.0015)
55+
// Elapsed event at 08:42:49.555362 (15.0015)
56+
// Elapsed event at 08:42:49.570364 (15.0015)
57+
// Elapsed event at 08:42:49.585365 (15.0015)
58+
// Elapsed event at 08:42:49.605367 (20.002)
59+
// Elapsed event at 08:42:49.620369 (15.0015)
60+
// Elapsed event at 08:42:49.635370 (15.0015)
61+
// Elapsed event at 08:42:49.650372 (15.0015)
62+
// Elapsed event at 08:42:49.665373 (15.0015)
63+
// </Snippet1>

0 commit comments

Comments
 (0)