Reputation: 2248
I've got a function that downloads a website:
let downloadPage (address : string) =
async
{
// do some magic here
}
It's type is "string -> Async string".
I want to download several pages - let "pagesToDownload" be a seq containing all of them. Then I can write:
pagesToDownload
|> Seq.map downloadPage
|> Async.Parallel
|> Async.RunSynchronously
This works fine, however it takes some time to accomplish. I'm planning to use this function in my UI, so it would be nice to provide e.g. a ProgressBar.
I found a nice article on using a ProgressBar in WPF: http://elegantcode.com/2009/07/03/wpf-multithreading-using-the-backgroundworker-and-reporting-the-progress-to-the-ui/
but I can't see how to combine these two ideas. The module that downloads websites is written in F#, while UI (ViewModel and View) - in C#.
Upvotes: 3
Views: 587
Reputation: 564751
One simple way to handle this is to use FSharp.ViewModule's Progress support. It includes a ProgressManager
class, which provides a functional style API to update progress, and internally wraps a Progress<T>
for you.
This makes it simple to bind to directly from the WPF UI. For an example, see the Visual F# Power Tools Rename dialog. Just make sure to create the instance in your VM on the main thread/SynchronizationContext, and it'll "just work". (This typically just means building this in a let binding or similar in the ViewModel type.)
If you don't want to take on the dependency for FSharp.ViewModule
(which I'd recommend and suggest is worthwhile if you're using F# for WPF backed MVVM ViewModels), you could easily adapt the code linked above to your scenario.
Upvotes: 3