F# 中的异步等待

Async Await in F#

我正在将本实验中的一些 C# 重写为 F#:https://github.com/Microsoft/TechnicalCommunityContent/tree/master/IoT/Azure%20Stream%20Analytics/Session%202%20-%20Hands%20On

我正在进行练习 6,#17 - 创建 SimpleEventProcessor 类型。
我想实现 CloseAsync 方法

C#

async Task IEventProcessor.CloseAsync(PartitionContext context, CloseReason reason)
    {
        Debug.WriteLine("Processor Shutting Down. Partition '{0}', Reason: '{1}'.", context.Lease.PartitionId, reason);
        if (reason == CloseReason.Shutdown)
        {
            await context.CheckpointAsync();
        }
    }

我是这样开始的:

member this.CloseAsync(context, reason) = 
    Debug.WriteLine("Processor Shutting Down. Partition '{0}', Reason: '{1}'.", context.Lease.PartitionId, reason)
    match reason with 
    | CloseReason.Shutdown -> await context.CheckpointAsync()
    | _ -> ()

但我有两个问题:

  1. 如何 return 在 F# 世界中等待?
  2. 如何 return NOT 大小写 -> C# 忽略这种可能性。
  1. 如果值的类型为 Async<'T>,您可以直接 return 不带任何关键字。如果它有类型 TaskTask<'T>,你可以做 |> Async.AwaitTask.

  2. 你可以returnasync { return () }.

所以你得到这个:

member this.CloseAsync(context, reason) = 
    Debug.WriteLine("Processor Shutting Down. Partition '{0}', Reason: '{1}'.", context.Lease.PartitionId, reason)
    match reason with 
    | CloseReason.Shutdown -> context.CheckpointAsync() |> Async.AwaitTask
    | _ -> async { return () }

另一种可能性是将整个块放在 async 工作流程中,并使用 return! 表示 1,return 表示 2:

member this.CloseAsync(context, reason) = 
    async {
        Debug.WriteLine("Processor Shutting Down. Partition '{0}', Reason: '{1}'.", context.Lease.PartitionId, reason)
        match reason with 
        | CloseReason.Shutdown -> return! context.CheckpointAsync() |> Async.AwaitTask
        | _ -> return ()
    }

事实上,使用异步工作流允许您像 C# 一样删除 () 案例:

member this.CloseAsync(context, reason) = 
    async {
        Debug.WriteLine("Processor Shutting Down. Partition '{0}', Reason: '{1}'.", context.Lease.PartitionId, reason)
        if reason = CloseReason.Shutdown then
            return! context.CheckpointAsync() |> Async.AwaitTask
    }