<Query Kind="FSharpProgram">
  <Reference>FSharp.Core.dll</Reference>
  <Reference>Hopac.dll</Reference>
  <Reference>Hopac.Core.dll</Reference>
</Query>

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

open Hopac
open Hopac.Core
open Hopac.Infixes
    
let achan = Ch<int> ()

let acount = ref 2
let adone = TaskCompletionSource<unit> ()
let m = 1000000000

let cons = 
    let rec loop n = job {
        let! n' = achan
        if n' % 100 = 0 then printfn "... %d : %d" n n'
        do! timeOutMillis 10
        
        if n > m then 
            if Interlocked.Decrement acount = 0 then adone.SetResult ()
            return ()
        else 
            return! loop (n+1)
        }
    start (loop 1)

let prod = 
    let rec loop n = job {
        //do! timeOutMillis 0
        do! achan *<- n
        
        if n > m then 
            if Interlocked.Decrement acount = 0 then adone.SetResult ()
            return ()
        else 
            return! loop (n+1)
        }
    start (loop 1)

adone.Task.Wait ()
printfn "..."