In my F# (FsXaml/Code Behind) application, I would like to use a progress bar without the utilisation of a background worker as I do in C#. Based on an article on the internet (the link is here), I tried to use asynchronous workflows.
I created code based (to some extend) on the examples in the aforementioned article, but it did not work as I had expected. The current thread (UI thread) is still blocked as if no async code was there. No switching to a background thread occurs. The progress bar is activated only after the long running operation has been finished. Removing the onThreadPool function has no effect.
My question is: What is wrong in my code and how to make it right?
type MainWindowXaml = FsXaml.XAML<"XAMLAndCodeBehind/MainWindow.xaml">
type MainWindow() as this =
inherit MainWindowXaml()
//....some code....
let ButtonClick _ =
//....some code....
let longRunningOperation() = //....some long running operation (reading from Google Sheets)....
let progressBar() = this.ProgressBar.IsIndeterminate <- true
let doBusyAsync progress operation =
progress
async
{
do! operation
}
|> Async.StartImmediate
let onThreadPool operation =
async
{
let context = System.Threading.SynchronizationContext.Current
do! Async.SwitchToThreadPool()
let! result = operation
do! Async.SwitchToContext context
return result
}
let asyncOperation progress operation =
async { operation }
|> onThreadPool
|> doBusyAsync progress
(progressBar(), longRunningOperation()) ||> asyncOperation
do
//....some code....
this.Button.Click.Add ButtonClick