0
  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>'
Aksen P
  • 4,564
  • 3
  • 14
  • 27
Andrew
  • 23
  • 2

1 Answers1

1

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
Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553