<Query Kind="FSharpProgram" />

open System
open System.Threading
open System.Threading.Tasks

let tid () = Thread.CurrentThread.ManagedThreadId;

let a = new MailboxProcessor<int> (fun inbox -> async { () })
    
let b = new MailboxProcessor<int> (fun inbox -> async { () })
    
let c = new MailboxProcessor<int> (fun inbox ->
    let rec loop (tx:Task<int>) (ty:Task<int>) = async {
        let! tz = Async.AwaitTask (Task.WhenAny (tx, ty))
        let! z = Async.AwaitTask tz

        if tz = tx then
            printfn "[%d] x: %d" (tid()) z
            let tx = Async.StartAsTask (a.Receive ())
            return! loop tx ty
            
        else
            printfn "[%d] y: %d" (tid()) z
            let ty = Async.StartAsTask (b.Receive ())
            return! loop tx ty
        }
        
    let init () = async {
        let tx = Async.StartAsTask (a.Receive ())
        let ty = Async.StartAsTask (b.Receive ())
        return! loop tx ty
        }
        
    init ())
 
//a.Start ()
//b.Start ()
c.Start ()

a.Post 10
b.Post 20
b.Post 30
b.Post 40
a.Post 50
a.Post 60
a.Post 70

Console.ReadLine () |> ignore
//
