2011-08-16 66 views
4

我知道这个问题已经在这里问过,但我已经阅读了几个答案,但没有帮助我。WPF,MVVM和异步工作

我有一个组合框需要获取一些与数据库选择相关的信息(可能是失去焦点,在滚动期间停止一千个调用)。这些信息仅用于显示,并不重要,因此获得后台线程/任务听起来就像是完美的解决方案。尽管它需要几秒钟,因为它从一些非常大的表格中获得。用户应该可以自由地进行其他任务,因为这些信息实际上仅用于显示/参考。

This question拥护者使用后台工作者,但这种解决方案有两个问题。 1)在工作人员已经运行的时候改变选择会带来问题。你可以不是第二次启动它,也就是说当它返回时它不再显示新选择的有效信息,或者尝试取消它(这并不总是有效)。 2)出于某种原因,我无法解释,实际访问后台工作数据库的方法返回速度较慢,如果方法在模型中比在ViewModel,我不认为它属于。我真的不知道为什么。

This question有几张选票,但是OP的问题措辞很差,选定的答案只是说“是的,应该有效”。

This question's method看起来很有前景,但链接的视频只有一个小时(我看了整件事情),并且仅在10秒内触发调度器而未解释它。如果有人链接到一篇更深入地介绍这种方法的文章,那很好。

线程池,因为suggested here看起来可能是最好的方式,因为多个查询请求只是排队,而不会导致已经运行的错误。但是,它没有解释如何使用线程池,而是链接到MSDN文章。如果有人链接到一篇更深入地介绍这种方法的文章,那将是理想的,因为它似乎是更好的解决方案(当然,我可能是错的)。

我真的试图对这一个做我的研究,但大多数这些答案只是告诉你使用什么方法,而不是如何使用它。我真的在寻找一个“如何做”。

+0

你想要异步做什么? 1)加载并填充组合框项目? 2)当用户选择一个项目时做一些其他的动作?您应该从问题中移除其他所有内容,以清楚说明您的实际问题。 –

+0

我认为这很清楚。我不需要填充组合框,我需要从数据库中获取与所做选择相关的信息,并在UI上显示这些信息。我的问题是,几个解决方案被提倡作为答案在stackoverflow没有解释。如果我删除问题的这一部分,恐怕我会得到那些答案的链接,或者类似的简单回答。 – Tyrsius

回答

6

确定。你的问题:

  1. 你有项目列表中选择控制
  2. 你有一个昂贵操作,返回从当前选定的项目一些结果(请注意,这种操作应该是昂贵的,不只是需要一段时间才能返回,以便让您担心同时没有太多它们) - 所以您需要并行执行它
  3. 返回的结果不受影响,仅显示 - 所以它是异步的
  4. 如果当前所选项目的变化,你不再想以前的结果 - 与以前的要求,应尽快,因为他们是昂贵

你应该做的取消,与最新的。NET技术:

  1. 使用无扩展器(Rx),成立了油门,使其只有当用户保持当前的选择,比如说,至少500毫秒(火你不想产卵很多很多TAKS当用户保持按压向下箭头键)
  2. 当节气门火灾,调用一个异步方法(异步CTP),其等待操作中的任务(长期运行的,以避免饥饿线程池),以及还放入取消令牌;保存当前选择以便稍后进行比较
  3. 当操作返回时,将结果设置到您的数据上下文(您的显示控件应该绑定到的位置) - 异步方法始终在UI线程上继续,因此您没有担心线程访问
  4. 如果油门触发并且存在未完成的任务/取消标记,则在根据#2产生新任务之前,首先使用取消标记取消任务。等待会因为任务被取消而抛出,但没关系,因为你不再需要它了。
  5. 此处没有并发问题,因为异步CTP始终在UI线程上继续。就您所有的操作而言,它们都是单线程的,不会彼此踩踏。

我想如果你使用Rx的异步CTP,它大约有10行代码。

注意:如果您的操作是而不是EXPENSIVE,则不必使用取消标记。只要允许任务运行完成,但忽略结果。但是,仍然建议您尽早取消数据库查询,尽管在客户端计算机上它并不昂贵,但它在服务器上很昂贵。

+0

这听起来很棒,但我不能将其标记为答案,直到我测试完毕,并且因为我不知道如何使用RX或异步CTP,我将不得不在网上寻找教程。如果你有一个可能会加快速度的链接。尽管谢谢你的回答非常好! – Tyrsius

3

你可以尝试使用异步绑定:

<ComboBox Name="theCombo" ... /> 
<TextBlock Text="{Binding Path=SomeSlowProperty, ElementName=theCombo, IsAsync=True}" />