2

MVVM-light を使用して複合 WPF アプリケーションを構築しています。MEF を使用してビューモデルが注入されたビューがあります。

DataContext = App.Container.GetExportedValue<ViewModelBase>(
                ViewModelTypes.ContactsPickerViewModel);

さらに、ビュー (スクリーンとユーザー コントロール) ごとにビューモデルを用意しています。コンストラクターは通常、次のようになります。

private readonly ICouchDataModel _couchModel;

    [ImportingConstructor]
    public ContactsPickerControlViewModel(ICouchDataModel couchModel)
    {
        _couchModel = couchModel;
        _couchModel.GetContactsListCompleted+=GetContactsListCompleted;
        _couchModel.GetConcatcsListAsync("Andy");
    } 

現在、いくつかのパフォーマンスの問題があります。すべてがただ遅いです。2種類の関連する質問があります

  1. DALメソッドを非同期的に呼び出す(私のcouchdbにアクセスする)正しい方法は何ですか? 待機/非同期? タスク?現在、各操作の周りに多くのラッパー(OnBegin、OnCompletion)を作成する必要があるため、 ThreadPool.QueueUserWorkItem 、 Action などでクレイジーなことを行う GetAsyncResult メソッドがあります。よりエレガントな呼び出し方法があることを願っています

  2. 現在、アプリケーションにいくつかの画面があり、各画面にはさまざまなカスタム UserControls があり、そのうちのいくつかは DB から同じデータ (またはわずかに変更) が必要です。質問:それらの間でデータソースを共有する正しい方法は何ですか? 編集ではなく、主にデータを表示しています。

    例: 画面 A: 連絡先ドロップダウン リスト ユーザー コントロール (UC1) と連絡先詳細ユーザー コントロール (UC2) があります。各ユーザー コントロールでは、ViewModel が DAL を呼び出しています。

    _couchModel.GetConcatcsListAsync("アンディ");

完了したら、結果データをプロパティに割り当てます。

List<ContactInfo> ContactsList = e.Resuls; 

ContactsList は、UC1 の DropDownListBox の ItemsSource にバインドされます。同じ話が UC2 でも起こります。したがって、DBへのまったく同じ呼び出しが2回行われます。また、UC1 がある画面 B に移動すると、画面 A から画面 B に移動するときに、DB に別の呼び出しを行います。

これらの相互作用を行う正しい方法は何ですか? たとえば、データを取得して UC にバインドします。

ありがとうございました。

4

1 に答える 1

1

Ad.1 Task.Factory
を使用してコードを非同期的に呼び出すことができると思います (そのため、OnBegin、OnCompletion を取り除くことができます)。または、メソッドを非同期にするよりも柔軟性が必要な場合。

広告。2
(私の意見では) 良い方法は、コンストラクターに注入される DatabaseService (シングルトン) を作成することです。DatabaseService 内では、コレクションを更新する (DAL を呼び出す) か、同じものを返す (ある種のキャッシュ) かを決定するロジックを実装できます。

次に、DAL の代わりに DatabaseService を直接呼び出すことができます。DatabaseService は、この呼び出しで何を行うかを決定します (DB からコレクションを取得するか、同じまたはわずかに変更された現在のコレクションを返します)。


編集:
DatabaseService は、ViewModel 間でオブジェクトのコレクションを共有するだけです。
「DBCacheService」という名前の方が適切かもしれません (おそらく、コレクションのキャッシュなどの特別なタスクにのみ使用します)。

あなたのアーキテクチャはわかりませんが、基本的にはそのサービスをクライアント アプリケーションに入れることができるので、計画は次のようになります。

  1. DatabaseService.cs を作成します。

    [Export(typeof(IDatabaseService))]
    public class DatabaseService : IDatabaseService
    {
        private List<object> _contacts = new List<object>();
    
        public async Task<List<object>> GetConcatcsList(string name)
        {
            if (_contacts.Count == 0)
            {
                //call DAL to get it
                //_contacts = await Task.Factory.StartNew(() => dal.GetContactsList(name));
            }
            else
            {
                //refresh list if required (there could be some condition)                
            }
    
            return _contacts;
        }
    }
    
  2. ViewModel のコンストラクターに IDatabaseService を追加します。

  3. DAL の代わりに IDatabaseService を呼び出します。

DatabaseService の非同期バージョンを選択した場合は、await を使用してメソッドを非同期に変更する必要があります。次のように、同期的に実行して(非同期にしたいときはいつでも)呼び出すことができます。

Task.Factory.StartNew(() => 
{
    var result = dbService.GetContactsList("Andy");
});

編集2:

タスク内の awaitable メソッドの呼び出し:

Task.Factory.StartNew(async () => 
{
    ListOfContacts = await _CouchModel.GetConatcsList ("Andy");
});
于 2013-06-22T13:19:02.677 に答える