我试图把它减少到尽可能小的重复,但它仍然有点长,我道歉.
我有一个F#项目引用一个C#项目,代码如下所示.
public static class CSharpClass {
public static async Task AsyncMethod(CancellationToken cancellationToken) {
await Task.Delay(3000);
cancellationToken.ThrowIfCancellationRequested();
}
}
Run Code Online (Sandbox Code Playgroud)
这是F#代码.
type Message =
| Work of CancellationToken
| Quit of AsyncReplyChannel<unit>
let mkAgent() = MailboxProcessor.Start <| fun inbox ->
let rec loop() = async {
let! msg = inbox.TryReceive(250)
match msg with
| Some (Work cancellationToken) ->
let! result =
CSharpClass.AsyncMethod(cancellationToken)
|> Async.AwaitTask
|> Async.Catch
// THIS POINT IS NEVER REACHED AFTER CANCELLATION
match result with
| Choice1Of2 _ -> …Run Code Online (Sandbox Code Playgroud) 我使用Async.Catch来处理异步工作流抛出的异常:
work
|> Async.Catch
|> Async.RunSynchronously
|> fun x -> match x with
| Choice1Of2 _ -> () // success
| Choice2Of2 ex -> // failure, handle exception
Run Code Online (Sandbox Code Playgroud)
今天我注意到Async.Catch不处理OperationCanceledExceptions.而不是从Async.Catch获得选择,异常不断冒泡直到它击中我.我希望下面的测试是红色的,但它是绿色的:
[<Test>]
let ``Async.Catch doesnt work on OperationCancelledExceptions``() =
use cancellationTokenSource = new System.Threading.CancellationTokenSource(1000)
let work = async {
while true do
do! Async.Sleep 100
}
(fun () -> work
|> Async.Catch
|> fun x -> Async.RunSynchronously (x, cancellationToken=cancellationTokenSource.Token)
|> ignore)
|> should throw typeof<System.OperationCanceledException>
Run Code Online (Sandbox Code Playgroud)
使用Async.Catch + Choices +匹配以及其他一些使用try/catch块评估一些异常似乎不正确......它看起来像下面这样,这太复杂了.除此之外,我想知道Async.Catch有什么用,因为我必须使用try/catch块...:
[<Test>]
let ``evaluating …Run Code Online (Sandbox Code Playgroud)