Winforms “模型视图演示者”模式中的缓慢操作

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的所有调用可能来自后台线程 让视图在主线程上调用演示者。然后,演示者必须在执行慢速操作时回调视

您如何处理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正在阻止主线程。但这也是一种选择,是的——我只是不确定它是否比其他选择更好。你试过了吗?