<Query Kind="FSharpProgram">
  <Reference>&lt;RuntimeDirectory&gt;\System.Windows.Forms.dll</Reference>
</Query>

open System
open System.Threading 
open System.Windows.Forms 
open System.Drawing 

//let form = new Form(Visible = true, Text = "Hello async world")
let form = new Form(
                Text = "Hello async world",
                Width = 400)

let textBox = new TextBox(
                Multiline = true,
                ScrollBars = ScrollBars.Vertical,    
                Dock = DockStyle.Fill, 
                ReadOnly = true)

textBox.Font <- new Font(
                FontFamily.GenericMonospace, 
                float32 14, 
                FontStyle.Bold)
    
form.Controls.Add(textBox)

let guiContext = SynchronizationContext.Current

let TID () = Thread.CurrentThread.ManagedThreadId

let flag = ref true

let task number = async {
    //let counter = ref 0
    //let mutable counter = 0
    let rnd = new Random(number)
    while !flag do
        //counter := !counter + 1
        //counter <- counter + 1
        let th1 = TID()  // thread pool
        
        do! Async.Sleep (rnd.Next(1000, 7000)) // simulate long computation
        let th2 = TID()  // thread pool
        
        do! Async.SwitchToContext(guiContext)
        let tgui = TID()  // GUI
        
        let line = sprintf "task=%d, th1=%2d, th2=%2d, tgui=%2d" number th1 th2 tgui
        printfn "%s" line
        textBox.Text <- sprintf "%s%s\r\n" textBox.Text line
        textBox.SelectionStart <- textBox.Text.Length
        textBox.ScrollToCaret()
        
        do! Async.SwitchToThreadPool()
} 

// ---------------------------------------
// start gui linqpad

using (form) (fun f ->
    [task 1; task 2; task 3] |> Async.Parallel |> Async.Ignore |> Async.Start         
    f.ShowInTaskbar <- true
    f.ShowDialog() |> ignore
    flag := false
    printfn "done"
    )
    
// ---------------------------------------
// start gui exe

(*
[<System.STAThread>]
do 
    [ task 1; task 2; task 3] |> Async.Parallel |> Async.Ignore |> Async.Start         
    Application.EnableVisualStyles()
    Application.Run(form)
*)

// ---------------------------------------