F#异步和WPF进度条

3

我有一个下载网站的函数:

let downloadPage (address : string) =
    async
        {
             // do some magic here
        }

它的类型是“字符串 -> 异步字符串”。

我想下载几个页面 - 让“pagesToDownload”成为包含所有页面的序列。然后我可以写:

pagesToDownload
|> Seq.map downloadPage
|> Async.Parallel
|> Async.RunSynchronously

这个功能可以正常运行,但是需要一些时间来完成。我计划在我的UI中使用此函数,因此提供一个ProgressBar会很好。
我找到了一篇关于在WPF中使用ProgressBar的好文章:http://elegantcode.com/2009/07/03/wpf-multithreading-using-the-backgroundworker-and-reporting-the-progress-to-the-ui/,但我不知道如何将这两个想法结合起来。下载网站的模块是用F#编写的,而UI(ViewModel和View)则用C#编写。

你可以接受 IProgress<T>,并在下载一堆页面的方法中将默认的 Progress<T> 实现作为参数使用。 - Patryk Ćwiek
1个回答

3
一种处理此问题的简单方法是使用FSharp.ViewModule's Progress支持。它包括一个ProgressManager类,提供了一个函数式API来更新进度,并在内部为您包装了一个Progress<T>
这使得直接从WPF UI绑定变得很简单。例如,可以参考Visual F# Power Tools重命名对话框。只需确保在主线程/同步上下文中在VM中创建实例,就可以"立即工作"。 (通常,这仅意味着在ViewModel类型中构建一个let binding或类似内容。)
如果不想承担FSharp.ViewModule的依赖关系(如果您正在使用F#进行WPF支持的MVVM ViewModel,则我建议并建议这是值得的),则可以轻松地将上面链接的代码适应于您的情况。

谢谢Reed,不幸的是这两个链接都失效了。你有其他的例子吗? - Goswin Rothenthal
@Goswin 我刚刚修复了链接 :) - Reed Copsey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接