WPF,MVVM和异步工作

Kye*_*ica 4 wpf asynchronous dispatcher backgroundworker threadpool

我知道这个问题之前已经被问过了,但我已经阅读了几个没有帮助我的答案.

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

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

这个问题有几个选票,但OP的问题措辞非常糟糕,所选答案只是说"是的,应该有效".

这个问题的方法看起来很有希望,但链接的视频是一个小时(我看了整个事情),并且仅在10-15秒内触及调度员而没有解释它.如果有人链接到更深入地介绍此方法的文章,那就更好了.

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

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

Ste*_*ung 6

好.你的问题:

  1. 您有一个包含项目列表的选择控件
  2. 你有一个昂贵的操作,从当前选择的项目返回一些结果 (请注意,此操作应该是昂贵的,而不是只需要时间返回,以便让你担心不会同时拥有太多的) -所以你需要并行完成
  3. 返回的结果不会被执行,只显示 - 所以它是异步的
  4. 如果当前所选项目发生变化,您将不再需要之前的结果 - 之前的请求应尽快取消,因为它们很昂贵

你应该做什么,使用最新的.NET技术:

  1. 使用Reactive Extensions(Rx),设置一个节流阀,使其仅在用户保持当前选择时触发,比如至少500ms(当用户持续按下向下箭头键时,您不希望产生许多tak) )
  2. 当节气门触发时,调用异步方法(Async CTP)等待任务中的操作(长时间运行以避免使线程池挨饿),并且还放入取消令牌; 保存当前选择以便稍后进行比较
  3. 当操作返回时,将结果设置为数据上下文(显示控件应该绑定到的) - 异步方法始终在UI线程上继续,因此您不必担心线程访问
  4. 如果节流触发并且存在未完成的任务/取消令牌,则在按照#2生成新任务之前,首先使用取消令牌取消该任务.await将因为任务被取消而抛出,但没关系,因为你不再需要它了.
  5. 这里没有并发问题,因为Async CTP始终在UI线程上继续.就您的所有操作而言,它们都是单线程的,不会相互踩踏.

我想如果你使用带有Rx的Async CTP,它大约有10行代码.

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