2

我正在使用 MVVM-light 构建复合 WPF 应用程序。我有使用 MEF 将 ViewModel 注入其中的视图:

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

此外,我对每个视图(屏幕和用户控件)都有 ViewModel,其中构造函数通常如下所示:

private readonly ICouchDataModel _couchModel;

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

目前,我有一些性能问题。一切都很缓慢。我有两种相关的问题

  1. 异步调用 DAL 方法(访问我的 couchdb)的正确方法是什么?等待/异步?任务?因为目前我必须围绕每个操作编写很多包装器(OnBegin,OnCompletion),所以我有 GetAsyncResult 方法可以用 ThreadPool.QueueUserWorkItem ,Action 等做一些疯狂的事情。我希望有更优雅的调用方式

  2. 目前,我的应用程序中有一些屏幕,在每个屏幕上,都有不同的自定义用户控件,其中一些需要来自 DB 的相同数据(或略有更改)。问题:在它们之间共享数据源的正确方法是什么?我主要是查看数据,而不是编辑。

    示例:在屏幕 A 上:我有联系人下拉列表用户控件 (UC1) 和联系人详细信息用户控件 (UC2)。在每个用户控件中,他们的 ViewModel 都在调用 DAL:

    _couchModel.GetConcatcsListAsync("Andy");

完成后,我将结果数据分配给一个属性:

List<ContactInfo> ContactsList = e.Resuls; 

ContactsList 绑定到 UC1 中 DropDownListBox 的 ItemsSource。同样的故事也发生在 UC2 中。所以我最终得到了 2 次完全相同的 DB 调用。此外,如果我去有 UC1 的屏幕 B,当我将从屏幕 A 转到屏幕 B 时,我将再次调用 DB。

进行这些交互的正确方法是什么?例如获取数据并将其绑定到 UC。

谢谢你。

4

1 回答 1

1

Ad.1
我认为您可以简单地使用 Task.Factory 来异步调用代码(因为您可以摆脱 OnBegin、OnCompletion),或者如果您需要更大的灵活性,则可以使方法异步。

广告。2
最好的方法(在我看来)是创建 DatabaseService(单例),它将被注入到构造函数中。在 DatabaseService 中,您可以实现一些逻辑来确定是要刷新集合(调用 DAL)还是返回相同的集合(它将是某种缓存)。

然后您可以直接调用 DatabaseService 而不是 DAL,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. 将 IDatabaseService 添加到 ViewModel 的构造函数中。

  3. 调用 IDatabaseService 而不是 DAL。

如果您选择异步版本的 DatabaseService,那么您需要使用 await 并将您的方法更改为异步。您也可以同步执行它并像这样调用它(只要您希望它是异步的):

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

编辑2:

在 Task 中调用 awaitable 方法:

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