Skip to content

Instantly share code, notes, and snippets.

@TheAngryByrd
Last active February 20, 2024 04:58
Show Gist options
  • Save TheAngryByrd/4e77af9c8b563b8ec29929d792781898 to your computer and use it in GitHub Desktop.
Save TheAngryByrd/4e77af9c8b563b8ec29929d792781898 to your computer and use it in GitHub Desktop.
F# Main Async
module Main =
open System
open System.Threading
let inline tryCancel (cts : CancellationTokenSource) =
try
cts.Cancel()
with :? ObjectDisposedException as e ->
// if CTS is disposed we're probably exiting cleanly
()
let setupCloseSignalers (cts : CancellationTokenSource) =
Console.CancelKeyPress.Add(fun _ ->
printfn "CancelKeyPress"
tryCancel cts
)
System.Runtime.Loader.AssemblyLoadContext.Default.add_Unloading(fun _ ->
printfn "AssemblyLoadContext unload"
tryCancel cts
)
AppDomain.CurrentDomain.ProcessExit.Add(fun _ ->
printfn "ProcessExit"
tryCancel cts
)
let mainAsync (argv : string array) = async {
do! Async.SwitchToThreadPool()
printfn "Doing work!"
do! Async.Sleep(1000)
printfn "Work done"
return 0
}
[<EntryPoint>]
let main argv =
use cts = new CancellationTokenSource()
setupCloseSignalers cts
Async.RunSynchronously(mainAsync argv, cancellationToken=cts.Token)
module Task =
open System.Threading
open System.Threading.Tasks
/// <summary>Queues the specified work to run on the thread pool. Helper for Task.Run</summary>
let runOnThreadpool (cancellationToken : CancellationToken) (func : unit -> Task<'b>) = Task.Run<'b>(func, cancellationToken)
/// <summary>Helper for t.GetAwaiter().GetResult()</summary>
let runSynchounously (t : Task<'b>) = t.GetAwaiter().GetResult()
module MainTask =
open System
open System.Threading
open System.Threading.Tasks
let inline tryCancel (cts : CancellationTokenSource) =
try
cts.Cancel()
with :? ObjectDisposedException ->
// if CTS is disposed we're probably exiting cleanly
()
let setupCloseSignalers (cts : CancellationTokenSource) =
Console.CancelKeyPress.Add(fun _ ->
printfn "CancelKeyPress"
tryCancel cts
)
System.Runtime.Loader.AssemblyLoadContext.Default.add_Unloading(fun _ ->
printfn "AssemblyLoadContext unload"
tryCancel cts
)
AppDomain.CurrentDomain.ProcessExit.Add(fun _ ->
printfn "ProcessExit"
tryCancel cts
)
let mainAsync (ctoken : CancellationToken) (argv : string array) = task {
printfn "Doing work!"
do! Task.Delay(1000, ctoken)
printfn "Work done"
return 0
}
[<EntryPoint>]
let main argv =
use cts = new CancellationTokenSource()
setupCloseSignalers cts
Task.runOnThreadpool cts.Token (fun () -> (mainAsync cts.Token argv))
|> Task.runSynchounously
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment