Nel mio F# (FsXaml/Codice Dietro) applicazione, vorrei utilizzare una barra di avanzamento, senza l'utilizzo di un operaio di sfondo come faccio in C#. Basato su un articolo su internet (il link è qui), ho provato a utilizzare flussi di lavoro asincroni.
Ho creato il codice di base (in certa misura) su esempi riportati nel predetto articolo, ma non ha funzionato come mi aspettavo. Il thread corrente (UI thread) è ancora bloccato, come se non async codice che c'era. Nessuna commutazione a un thread in background si verifica. La barra di avanzamento viene attivato solo dopo una lunga esecuzione operazione è stata completata. Rimozione del onThreadPool funzione non ha alcun effetto.
La mia domanda è: Cosa c'è di sbagliato nel mio codice, e come farlo giusto?
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