Async Tunggu di F#

Saya menulis ulang beberapa C# di lab ini ke F#: https://github.com/Microsoft/TechnicalCommunityContent/tree/master/IoT/Azure%20Stream%20Analytics/Session%202%20-%20Hands%20On

Saya sedang mengerjakan Latihan 6, #17 - membuat tipe SimpleEventProcessor.
Saya ingin mengimplementasikan metode 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();
        }
    }

dan saya mulai seperti ini:

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()
    | _ -> ()

tapi saya punya 2 pertanyaan:

  1. Bagaimana cara saya kembali menunggu di dunia F#?
  2. Bagaimana cara mengembalikan kasus NOT -> C# abaikan saja kemungkinan itu.

person Jamie Dixon    schedule 25.05.2017    source sumber


Jawaban (1)


  1. Jika nilainya bertipe Async<'T>, Anda cukup mengembalikannya tanpa kata kunci apa pun. Jika bertipe Task atau Task<'T>, Anda dapat melakukan |> Async.AwaitTask.

  2. Anda dapat mengembalikan async { return () }.

Jadi Anda mendapatkan ini:

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 () }

Kemungkinan lain adalah dengan menempatkan seluruh blok dalam alur kerja async, dan menggunakan return! untuk 1 dan return untuk 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 ()
    }

Faktanya, menggunakan alur kerja async memungkinkan Anda menghapus kasus () dengan cara yang sama seperti 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
    }
person Tarmil    schedule 25.05.2017
comment
IEventProcessor CloseAsync mengembalikan Tugas. Jadi | CloseReason.Shutdown -› konteks.CheckpointAsync() berfungsi. Perlu mencari cara untuk mengembalikan tugas kosong - person Jamie Dixon; 25.05.2017
comment
Ini berhasil: cocokkan alasan dengan | CloseReason.Shutdown -› konteks.CheckpointAsync() | _ -› Tugas.Tugas Selesai - person Jamie Dixon; 25.05.2017
comment
Ah benar maaf, saya salah membaca pertanyaan Anda, entah kenapa saya mengira Anda mengonversi dari Task ke Async selain beralih dari C# ke F#. - person Tarmil; 25.05.2017
comment
Jika Anda menggunakan F# async alih-alih Task, bukankah konvensi akan memberi nama metode AsyncClose alih-alih CloseAsync? - person Bent Tranberg; 26.05.2017