Skip to content

Instantly share code, notes, and snippets.

@eulerfx
Created June 21, 2018 20:58
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eulerfx/96d0a09e33cc100aa5792e9481805134 to your computer and use it in GitHub Desktop.
Save eulerfx/96d0a09e33cc100aa5792e9481805134 to your computer and use it in GitHub Desktop.
F# Async Race
let race (a:Async<'a>) (b:Async<'a>) : Async<'a * Async<'a>> = async {
return!
Async.FromContinuations <| fun (ok,err,cnc) ->
let state = ref 0
let iv = new TaskCompletionSource<_>()
let ok a =
if (Interlocked.CompareExchange(state, 1, 0) = 0) then
ok (a, iv.Task |> Async.AwaitTask)
else
iv.SetResult a
let err (ex:exn) =
if (Interlocked.CompareExchange(state, 1, 0) = 0) then err ex
else iv.SetException ex
let cnc ex =
if (Interlocked.CompareExchange(state, 1, 0) = 0) then cnc ex
else iv.SetCanceled ()
Async.StartThreadPoolWithContinuations (a, ok, err, cnc)
Async.StartThreadPoolWithContinuations (b, ok, err, cnc) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment