BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

何时在WPF中使用Async及Reactive Extensions

| 作者 Jonathan Allen 关注 594 他的粉丝 ,译者 邵思华 关注 3 他的粉丝 发布于 2013年3月29日. 估计阅读时间: 3 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

Ian Griffiths发布了包含六部分的一系列文章,讨论了何时应该、及何时不应在WPF中使用.NET 4.5中的async特性。这个系列始于一篇名为“Too Much, Too Fast with WPF and Async”的贴子。

有了async这件神器,似乎有人就想在应用程序中到处使用,并时时刻刻调用它。不幸的是,如果每个batch的大小(即async调用之间的时间差)小于创建Task对象及对应的上下文切换的消耗,这种情况下async就不那么好用了。

Ian写道,大的batch可以减少任务完成的总体时间,但又可能影响到UI的响应。

虽然这远远快于8.5秒的情况,但我们也作出了牺牲:那个总体速度较慢的例子反而为UI更快地提供了有用的信息。实际上,用户可能会更倾向于较慢的那个版本,因为有用的信息能够立即出现,你可能不会感觉到装载整个列表的速度慢了三倍——将整个列表拖动到底部的时间说不定都远远长于8.5秒了。按照这个重要的指标来看,单纯地使用异步方法是更好的选择:它为用户更快地提供了有用的信息。

Ian Griffiths也谈到了使用线程池与WPF 4.5中的集合同步(Collection Synchronization)新特性。如果你要使用ConfigureAwait(false)方法来避免强制在UI线程上进行处理,这项技巧也是必不可少的。

调用ConfigureAwait表示我们并不关心方法在哪个线程上继续执行。要点在于,某个不能立即完成的读操作最终会完成,而方法的余下部分会在一个线程池的线程上延迟执行。这意味着使用await不会再导致WPF的调度占用。但当然,它也意味着列表的全部更新都会发生在一个工作线程上,因此我们需要使用同样的小花招以避免产生问题:要么等到方法完成后再绑定数据并显示列表,要么就必须处理跨线程的变更通知。

Ian所演示的另一个技巧是使用Reactive Extensions分块处理数据。它使用了Buffer函数将batch大小限制为100ms,或是将总数限制为5000个(取决于先达到哪个数值),然后通过ObserveOnDispatcher函数将其封装回送至UI线程。这种模式比起其它技巧显得冗余,但它“几乎能够立即开始显示[…]数据,并在2.3秒内完成加载并显示所有数据”,这比原来的同步实现还是有所改进。

查看英文原文When to Use WPF with Async and Reactive Extensions


感谢杨赛对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT