Created
January 18, 2014 10:21
-
-
Save Thorium/8488563 to your computer and use it in GitHub Desktop.
Set timeout or cancel Using task based async, won't block the thread.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open System | |
open System.Threading | |
/// Async timer to perform actions | |
let timer interval scheduledAction = async { | |
do! interval |> Async.Sleep | |
scheduledAction() | |
} | |
/// Add action to timer, return cancellation-token to cancel the action | |
let scheduleAction interval scheduledAction = | |
let cancel = new CancellationTokenSource() | |
Async.Start (timer interval scheduledAction, cancel.Token) | |
cancel | |
// Basic idea from: http://msdn.microsoft.com/en-us/library/ee370246.aspx | |
/// Agent to maintain a queue of scheduled tasks that can be canceled. | |
/// It never runs its processor function, so it doesn't do anything. | |
let scheduleAgent = new MailboxProcessor<Guid * CancellationTokenSource>(fun _ -> async { () }) | |
let postToken = scheduleAgent.Post | |
let cancelAction(agentId) = | |
scheduleAgent.TryScan((fun (aId, source) -> | |
let action = | |
async { | |
source.Cancel() | |
return agentId | |
} | |
if (agentId = aId) then | |
Some(action) | |
else | |
None), 100) // timeout: if queue is empty, wait 100ms to get a value. | |
|> Async.RunSynchronously | |
// Testing: | |
// Do action when timeout: | |
let notifyTimeout1() = Console.WriteLine "5 seconds elapsed." | |
let id1 = Guid.NewGuid() | |
let token1 = scheduleAction 5000 notifyTimeout1 | |
postToken(id1, token1) | |
// Cancel action before timeout: | |
let notifyTimeout2() = Console.WriteLine "This won't happen" | |
let id2 = Guid.NewGuid() | |
let token2 = scheduleAction 3000 notifyTimeout2 | |
postToken(id2, token2) | |
cancelAction(id2) |> ignore |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment