WPF,MVVM和异步工作

时间:2011-08-16 20:06:38

标签: wpf asynchronous backgroundworker threadpool dispatcher

我知道此问题已在此处提出,但我已经阅读了几个对我没有帮助的答案。

我有一个ComboBox需要从数据库中获取与选择相关的一些信息(可能是丢失焦点,在滚动期间停止一千次调用)。此信息仅供显示,而不是关键,因此获得后台线程/任务听起来就像是完美的解决方案。它确实需要几秒钟,因为它从一些非常大的表中得到计数。用户应该可以自由地继续执行其他任务,因为这些信息仅用于显示/参考。

This question提倡使用后台工作者,但此解决方案有两个问题。 1)在工作人员已经运行时更改选择会引入问题。您可以不是第二次启动它,这意味着当它返回时它不再显示新选择的有效信息,或者尝试取消它(这并不总是有效)。 2)由于某些原因我无法解释,实际访问后台工作程序的数据库的方法如果方法在模型中比在ViewModel中返回更慢,我认为它不属于ViewModel。我真的不知道为什么。

This question有几张选票,但OP的问题措辞非常糟糕,选定的答案只是说“是的,应该有用。”

This question's method看起来很有希望,但链接的视频只有一个小时(我观看了整个事情),并且在没有解释的情况下只接触调度员10-15秒。如果某人有更深入地介绍这种方法的文章的链接,那就更好了。

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

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

2 个答案:

答案 0 :(得分:6)

行。你的问题:

  1. 您有一个包含项目列表的选择控件
  2. 你有一个昂贵的操作,从当前选中的项目返回一些结果(请注意,此操作应该很昂贵,而不仅仅需要时间才能返回,以便你有没有担心同时没有太多的东西) - 所以你需要并行执行
  3. 返回的结果不会被执行,只显示 - 所以异步
  4. 如果当前所选项目发生变化,您将不再需要之前的结果 - 之前的请求应尽快取消,因为它们昂贵
  5. 使用最新的.NET技术应该做些什么:

    1. 使用Reactive Extensions(Rx),设置一个油门,以便只有当用户保持当前选择时才会触发,比如至少500ms(当用户持续按下时,你不想产生很多次数)向下箭头键)
    2. 当节气门触发时,调用异步方法(异步CTP)等待任务中的操作(长时间运行以避免使线程池匮乏),以及还放入了取消令牌;保存当前选择以便稍后进行比较
    3. 当操作返回时,将结果设置为数据上下文(显示控件应绑定到的) - 异步方法始终在UI线程上继续,因此您不必担心线程访问
    4. 如果油门激活并且有未完成的任务/取消令牌,则在按照#2生成新任务之前,首先使用取消令牌取消任务。 await将因为任务被取消而抛出,但这并不重要,因为你不再需要它了。
    5. 此处没有并发问题,因为Async CTP始终在UI线程上继续。就你所有的操作而言,它们都是单线程的,不会互相攻击。
    6. 我认为如果你使用带有Rx的Async CTP,它大约有10行代码。

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

答案 1 :(得分:3)

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

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