F#中的异步等待

时间:2017-05-25 12:17:51

标签: .net f# async-await c#-to-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. 如何在F#world中返回等待?
  2. 如何退回NOT案例 - > C#只是忽略了这种可能性。

1 个答案:

答案 0 :(得分:7)

  1. 如果值的类型为Async<'T>,则可以不带任何关键字返回。如果类型为TaskTask<'T>,则可以|> Async.AwaitTask

  2. 您可以返回async { return () }

  3. 所以你明白了:

    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
        }