F#: how to stop function by time limit

66 Views Asked by At
  let runWithTimeout (timeout: int) (action: unit -> 'a) : 'a option =
    let cts = new CancellationTokenSource(timeout)
    try
    let task = async { let! res = Task.Run(action, cts.Token)
                       return res }
    Some(Async.RunSynchronously(task))
    with :? OperationCanceledException -> None

But for Task.Run(action, cts.Token) :

Type constraint mismatch. The type 'Task<'a>' is not compatible with type 'Async<'b>'
1

There are 1 best solutions below

0
Tomas Petricek On BEST ANSWER

It is best not to try to mix Async with Task unless you know well what you are doing. In this case, you can implement the functionality very easily just using tasks. There are many options, but one nice approach is to use WhenAny to choose between your action and a task that waits for a given time and then returns None:

open System
open System.Threading
open System.Threading.Tasks

let runWithTimeout (timeout: int) (action: unit -> 'a) : 'a option =    
    let work = Task.Run(fun () -> Some(action()))
    let delay = Task.Delay(timeout).ContinueWith(fun t -> None)
    Task.WhenAny(work, delay).Result.Result

Related Questions in F#