3

您如何处理 Model-View-Presenter(或 MVC 或 MV-VM 或您正在使用的任何变体)中的缓慢操作?

当您在 WinForms 或 SWT/JFace 或您正在使用的任何桌面框架中操作缓慢时,您必须在后台线程上运行它以避免完全锁定应用程序。你在哪里处理这个?

我可以看到几个解决方案,但我对其中任何一个都不完全满意:

  1. 让视图调用始终在后台线程上调用演示者。这意味着视图必须处理来自演示者的所有调用可能来自后台线程。

  2. 让视图在主线程上调用演示者。演示者在执行慢速操作时必须回调视图,以便它可以在后台运行。

你平常都做什么?

编辑:我刚刚看到这篇文章: http: //www.codeproject.com/KB/threads/ThreadedExecuter.aspx。它基本上是2的实现。有没有人尝试过这样的事情?

4

4 回答 4

1

您可以使用服务器端到客户端框架(如 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 ...){
    }
});
于 2011-10-15T05:27:41.310 回答
1

视图可以从主线程调用演示者。演示者然后在工作线程中启动操作。并且视图(例如使用计时器)从主线程轮询演示者,以防止回调到视图中。问候,坦伯格

于 2009-01-26T17:02:23.600 回答
1

我对 tamberg 使用了一种非常相似的方法(即使用工作线程进行处理)。

主要区别在于与视图和表示模型的交互,它包含视图直接绑定到的额外状态,用于以下行为:

  • 输入禁用
  • 进度更新(使用 BackgroundWorker 相当简单)
  • 完成通知

通过将额外的状态放在演示模型而不是视图中,我可以交换视图(或者更常见的情况是,有两个视图指向同一个演示者)。

于 2009-06-10T17:17:45.123 回答
1

我已经使用来处理这个问题。所有对视图方法的调用都会被拦截并同步到 UI 线程。IView我们配置了我们的 AOP 框架(spring.net)来为从我们的基本接口继承的所有接口执行此操作。在演示者上,我们使用属性来指示这个运行缓慢的操作应该在后台运行。Presenter 方法看起来像这样:

// ...
[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;
}

如果您不熟悉 AOP,使用 AOP 并非易事,但在这种特殊情况下,它为我们节省了 UI 中的大量基础架构代码,现在我们几乎可以零努力地开发响应式 UI。

于 2011-10-16T14:09:48.070 回答