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,6153 gold badges16 silver badges27 bronze badges
1 Answer 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
answered Apr 8, 2023 at 20:27
Tomas Petricek
244k22 gold badges397 silver badges563 bronze badges
Sign up to request clarification or add additional context in comments.
Comments
lang-ml