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

私はこれを処理するためにを使用しました。ビューメソッドへのすべての呼び出しはインターセプトされ、UIスレッドに同期されます。IViewベースインターフェイスから継承するすべてのインターフェイスに対してこれを行うように、AOPフレームワーク(spring.net)を構成しました。プレゼンターでは、属性を使用して、この低速実行操作をバックグラウンドで実行する必要があることを示します。プレゼンターメソッドは次のようになります。

// ...
[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 に答える
1

ビューはメインスレッドからプレゼンターを呼び出すことができます。次に、プレゼンターはワーカースレッドで操作を開始します。また、ビュー(タイマー付きなど)は、ビューへのコールバックを防ぐために、メインスレッドからプレゼンターをポーリングします。よろしく、タンバーグ

于 2009-01-26T17:02:23.600 に答える
1

私は tamberg とかなり似たアプローチを使用しています (つまり、ワーカー スレッドを使用して処理を行います)。

主な違いは、ビューとプレゼンテーション モデルとの相互作用です。これには、ビューが次のような動作のために直接バインドする追加の状態が保持されます。

  • 入力無効化
  • 進行状況の更新 (BackgroundWorker を使用するとかなり簡単)
  • 完了通知

ビューではなくプレゼンテーション モデルに余分な状態を配置することで、ビューを交換できます (または、より一般的なケースでは、2 つのビューが同じプレゼンターを指すようにします)。

于 2009-06-10T17:17:45.123 に答える
1

GWT のようなサーバーからクライアント側へのフレームワークで使用されるのと同じ asynccallback アプローチを使用できます。操作を実装するサービス ウィッチを記述し、標準メソッド return で結果を返す代わりに、メソッドの引数としてコールバック インターフェイスを使用します。

例 :

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 に答える