I have not found a way to specify the timeout to the operation - see the code snippet to see what I try to achieve.
type ResponseKind =
| Json of string
| Error of Exception
| Timeout
let download (wclient : WebClient) (timeout : int option) (base_url : Uri) (sub_url : string) : Async<ResponseKind> =
async {
let target_uri = Uri(base_url, sub_url)
try
let! result = wclient.AsyncDownloadString(target_uri)
return ResponseKind.Json result
with
| :? TimeoutException ->
return ResponseKind.Timeout
| _ as ex ->
return ResponseKind.Error ex
}
Now, I am aware that there are myriads of other ways to achieve the same, e.g. using WebRequest
instead. But maybe it is just a simple oversight of mine, not finding out how to set a timeout on the operation.
Ideas?
Update
Further investigation on my behalf led me to an FSSnippet which uses a timeout task in parallel to the task to be executed.
Reusing that approach in my context, yielded a modified version of my code:
type ResponseKind =
| Json of string
| Error of Exception
| Timeout
let await_download_with_timeout (task : Task<string>) (timeout : int) : Async<ResponseKind>=
async {
use cts = new CancellationTokenSource()
use timer = Task.Delay (timeout,cts.Token)
let! completed =
Task.WhenAny(task,timer)
|> Async.AwaitTask
if completed = (task :> Task)
then
cts.Cancel()
let! result = Async.AwaitTask task
if task.IsCompleted
then
return ResponseKind.Json result
else
return ResponseKind.Error (task.Exception)
else
return ResponseKind.Timeout
}
let download (wclient : WebClient) (timeout : int option) (base_url : Uri) (sub_url : string) : Async<ResponseKind> =
async {
let target_uri = Uri(base_url, sub_url)
try
match timeout with
| Some t ->
let dtask = wclient.DownloadStringTaskAsync(target_uri)
let! result = await_download_with_timeout dtask t
return result
| None ->
let! result = wclient.AsyncDownloadString(target_uri)
return ResponseKind.Json result
with
| :? TimeoutException ->
return ResponseKind.Timeout
| _ as ex ->
return ResponseKind.Error ex
}
Now, the problem remaining is that I am not sure if my detection of something else going wrong is okay.