No meu F# (FsXaml/Code-Behind) aplicação, eu gostaria de usar uma barra de progresso sem a utilização de um trabalho de fundo como eu fazer em C#. Baseado em um artigo na internet (o link está aqui), eu tentei usar assíncrona fluxos de trabalho.
Eu criei com base em código (em certa medida) nos exemplos, no referido artigo, mas não funcionou como eu esperava. O atual thread (thread de INTERFACE de utilizador) ainda está bloqueado, como se nenhum código assíncrono estava lá. Sem mudar para um segmento de plano de fundo ocorre. A barra de progresso é ativada apenas depois de longa operação foi concluída. Remover o onThreadPool função não tem efeito.
A minha pergunta é: o Que está errado no meu código e como fazê-lo direito?
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