Winforms “模型视图演示者”模式中的缓慢操作
您如何处理Model View Presenter(或MVC或M-V-VM或您正在使用的任何变体)中的慢速操作 当您在WinForms、SWT/JFace或正在使用的任何桌面框架中执行缓慢的操作时,您必须在后台线程上运行它,以避免完全锁定应用程序。你在哪里处理这件事 我可以看到一些解决方案,但我对其中任何一个都不完全满意:Winforms “模型视图演示者”模式中的缓慢操作,winforms,model-view-controller,user-interface,swt,mvp,aop,Winforms,Model View Controller,User Interface,Swt,Mvp,Aop,您如何处理Model View Presenter(或MVC或M-V-VM或您正在使用的任何变体)中的慢速操作 当您在WinForms、SWT/JFace或正在使用的任何桌面框架中执行缓慢的操作时,您必须在后台线程上运行它,以避免完全锁定应用程序。你在哪里处理这件事 我可以看到一些解决方案,但我对其中任何一个都不完全满意: 让视图调用始终在后台线程上调用演示者。这意味着视图必须处理来自presenter的所有调用可能来自后台线程 让视图在主线程上调用演示者。然后,演示者必须在执行慢速操作时回调视
编辑:我刚看到这篇文章:。它基本上是2的一个实现。有人尝试过类似的方法吗?视图可以从主线程调用演示者。然后,演示者在工作线程中启动该操作。视图(例如,使用计时器)从主线程轮询演示者,以防止回调到视图中。关于tamberg,我使用了与tamberg非常相似的方法(即使用工作线程进行处理) 主要区别在于与视图和表示模型的交互,它包含视图直接绑定到的额外状态,例如:
- 输入禁用
- 进度更新(使用BackgroundWorker非常简单)
- 完工通知
通过将额外的状态放在表示模型中而不是视图中,我可以交换视图(或者更常见的情况是,有两个视图指向同一个表示者)。您可以使用与GWT等服务器端到客户端框架相同的异步回调方法,只需编写一个实现您的操作的服务,而不是在标准方法返回中返回结果,而是使用回调接口作为方法的参数 例如:
class ServiceX {
void doFoo(x arg , y arg2 , callback arg3){
//do in your thread
arg3.success("with return variables you need")
// or
arg3.failed("with exception for example");
}
}
interface Callback {
void success(args...);
void failed(args ...);
}
in your view :
// do
ServiceX bar = // get your service
bar.doFoo(a1,a2,new CallBack(){
void succes(args ...){
}
void failed(args ...){
}
});
我曾经处理过这件事。所有对view方法的调用都被截获并同步到UI线程。我们将AOP框架(spring.net)配置为对继承自IView
基本接口的所有接口执行此操作。在演示者上,我们使用属性来指示此缓慢运行的操作应在后台运行。演示者方法如下所示:
// ...
[RunInBackground]
public void TakeSomeTimeToRetrieveSomeItems
{
var items = _svc.GetSomeItemsFromTheWeb();
_view.ShowItems(items); // synced to UI automatically; blocks in presenter
}
在我们看来,我们不需要做任何特别的事情:
// ...
public void ShowItems(IList<Item> items)
{
itemBindingSource.DataSource = items;
}
/。。。
公共无效显示项(IList项)
{
itemBindingSource.DataSource=项;
}
如果您不熟悉AOP,那么使用AOP并不是一件小事,但在这种特殊情况下,它为我们节省了大量UI中的基础结构代码,现在我们可以几乎不费吹灰之力地开发响应性UI。您的意思是(1)?如果在主线程上调用了presenter,则计时器将不会运行,而presenter正在阻止主线程。但这也是一种选择,是的——我只是不确定它是否比其他选择更好。你试过了吗?