Sto provando a fare una richiesta web asincrona a un URL che restituirà se la richiesta impiega troppo tempo. Sto usando il flusso di lavoro asincrono F # e la libreria System.Net.Http per farlo.async computation does not catch OperationCancelledException
Tuttavia, non riesco a rilevare le Task/OperationCancelledException generate dalla libreria System.Net.Http nel flusso di lavoro async
. Al contrario, l'eccezione viene sollevata al metodo Async.RunSynchronously, come si può vedere in questa analisi dello stack:
> System.OperationCanceledException: The operation was canceled. at
> Microsoft.FSharp.Control.AsyncBuilderImpl.commit[a](Result`1 res)
> at
> Microsoft.FSharp.Control.CancellationTokenOps.RunSynchronously[a](CancellationToken
> token, FSharpAsync`1 computation, FSharpOption`1 timeout) at
> Microsoft.FSharp.Control.FSharpAsync.RunSynchronously[T](FSharpAsync`1
> computation, FSharpOption`1 timeout, FSharpOption`1 cancellationToken)
> at <StartupCode$FSI_0004>[email protected]()
Il codice:
#r "System.Net.Http"
open System.Net.Http
open System
let readGoogle() = async {
try
let request = new HttpRequestMessage(HttpMethod.Get, "https://google.co.uk")
let client = new HttpClient()
client.Timeout <- TimeSpan.FromSeconds(0.01) //intentionally low to always fail in this example
let! response = client.SendAsync(request, HttpCompletionOption.ResponseContentRead) |> Async.AwaitTask
return Some response
with
| ex ->
//is never called
printfn "TIMED OUT"
return None
}
//exception is raised here
readGoogle()
|> Async.RunSynchronously
|> ignore
In generale, le eccezioni sono divertente con asincrono. Vuoi usare 'Async.Catch'. Il comportamento strano è causato quando l'eccezione viene ricostituita sul thread principale causando la traccia dello stack dispari. –
Ho provato a scrivere questo nello stile Async.Catch e il problema si verifica ancora. L'altra cosa è che se viene lanciato un altro tipo di eccezione, viene catturato correttamente. Mi chiedo se il modulo Async gestisce i token di cancellazione potrebbe essere un errore, forse sta interpretando erroneamente l'eccezione come una richiesta di cancellazione al modulo. – WiseGuyEh