首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >异步计算不能捕获OperationCancelledException

异步计算不能捕获OperationCancelledException
EN

Stack Overflow用户
提问于 2014-10-03 11:14:02
回答 1查看 488关注 0票数 8

我正在尝试向URL发出异步web请求,如果请求花费太长时间,该请求将返回。我使用F#异步工作流和System.Net.Http库来完成这个任务。

但是,我无法捕获由System.Net.Http库在async工作流中引发的Task/OperationCancelledExceptions。相反,异常是在Async.RunSynchronously方法中引发的,正如您在这个堆栈跟踪中看到的那样:

代码语言:javascript
复制
> 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>.$FSI_0004.main@()

守则:

代码语言:javascript
复制
#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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-04 00:41:01

取消总是与错误不同。在您的情况下,您可以覆盖AwaitTask的默认行为,如果任务被取消,则调用"cancel延续“,并以不同的方式处理它:

代码语言:javascript
复制
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
        return! ( 
            let t = client.SendAsync(request, HttpCompletionOption.ResponseContentRead)
            Async.FromContinuations(fun (s, e, _) ->
                t.ContinueWith(fun (t: Task<_>) -> 
                    // if task is cancelled treat it as timeout and process on success path
                    if t.IsCanceled then s(None)
                    elif t.IsFaulted then e(t.Exception)
                    else s(Some t.Result)
                )
                |> ignore
            )
        )
    with 
        | ex ->
            //is never called
            printfn "TIMED OUT" 
            return None
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26177963

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档