On the .NET platform, Windows Forms is the defacto-standard GUI library and it is not thread safe. This means that it is not safe to do anything with a form or any of the form's controls (GUI components) from any thread other than the one that created the form.
This is a serious headache for .NET developers and incorrect multithreaded code is a nightmare to debug.
Fortunately, the F# programming language greatly simplifies the task of adjusting GUIs from other threads. The fundamental concept is the same as the conventional solution on .NET: you create a message loop that queues operations that are to be evaluated on the GUI thread.
A GUI thread, new form and message loop may be created using:
let form = ref null
let make_form() =
form := new Form()
let thread = new Threading.Thread(make_form) in
Note that we have been careful to keep a reference to the form that was created by the new thread.
The form cannot be edited directly from the main thread. However, the form.Invoke() method allows us to queue arbitrary operations for execution on GUI thread and these operations may alter the form at will. Moreover, these operations may be specified as simple functions of the type unit -> unit in F#.
For example, the form may be hidden safely by executing this code on any thread:
form.Invoke(fun () -> form.Visible <- false)
Although this does not make windows forms thread-safe in F#, it does greatly simplify the thread-safe use of windows forms.