LA.27
LA.27

Reputation: 2248

F# Async and WPF ProgressBar

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

Answers (1)

Reed Copsey
Reed Copsey

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

Related Questions