我正在使用MVVM-light构建复合WPF应用程序。我有使用MEF将ViewModel注入其中的视图:
DataContext = App.Container.GetExportedValue<ViewModelBase>(
ViewModelTypes.ContactsPickerViewModel);
此外,我为每个View(Screens和UserControls)都有ViewModel,其中构造函数通常如下所示:
private readonly ICouchDataModel _couchModel;
[ImportingConstructor]
public ContactsPickerControlViewModel(ICouchDataModel couchModel)
{
_couchModel = couchModel;
_couchModel.GetContactsListCompleted+=GetContactsListCompleted;
_couchModel.GetConcatcsListAsync("Andy");
}
目前,我遇到了一些性能问题。一切都很慢。 我有两种相关的问题
异步调用DAL方法的正确方法是什么(访问我的couchdb)?等待/异步?任务?因为目前我必须围绕每个操作编写很多包装器(OnBegin,OnCompletion),所以我有GetAsyncResult方法,它使用ThreadPool.QueueUserWorkItem,Action等做一些疯狂的事情。 我希望有更优雅的方式来致电
目前,我的应用程序和每个屏幕上都有一些屏幕,有不同的自定义UserControl,其中一些需要来自DB的相同数据(或略有变化)。 问题:在它们之间共享数据源的正确方法是什么?我主要是查看数据,而不是编辑。
示例:屏幕A:我有联系人下拉列表用户控件(UC1),以及联系人详细信息用户控件(UC2)。在每个用户控件中,他们的ViewModel正在调用DAL:
_couchModel.GetConcatcsListAsync( “安迪”);
完成后,我将结果数据分配给一个属性:
List<ContactInfo> ContactsList = e.Resuls;
ContactsList绑定到UC1中DropDownListBox的ItemsSource。同样的故事发生在UC2中。所以我最终得到了两个完全相同的DB调用。 此外,如果我去屏幕B,我有UC1,我将再次拨打DB,当我从屏幕A转到屏幕B时。
进行这些互动的正确方法是什么?,例如获取数据并将其绑定到UC。
谢谢。
答案 0 :(得分:1)
<强> Ad.1 强>
我认为您可以简单地使用Task.Factory异步调用代码(因为您可以摆脱OnBegin,OnCompletion)或者如果您需要更多的灵活性,那么您可以使方法异步。
广告。 2 强>
我认为这样做的好方法是创建DatabaseService(singleton),它将被注入构造函数中。在DatabaseService中,您可以实现一些逻辑来确定是要刷新集合(调用DAL)还是返回相同的(它将是某种缓存)。
然后您可以直接调用DatabaseService而不是DAL,DatabaseService将决定如何处理此调用(从DB获取集合或返回相同或稍微修改过的当前集合)。
修改:
DatabaseService将简单地在ViewModels之间共享一组对象
也许名称“DBCacheService”更合适(您可能只将它用于特殊任务作为缓存集合)。
我不了解您的架构,但基本上您可以将该服务放在您的客户端应用程序中,因此计划将是:
创建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;
}
}
将IDatabaseService添加到ViewModel的构造函数中。
如果选择DatabaseService的异步版本,则需要使用等待并将方法更改为异步。您也可以同步执行并调用它(只要您希望它是异步的):
Task.Factory.StartNew(() =>
{
var result = dbService.GetContactsList("Andy");
});
<强> EDIT2:强>
在Task:
中调用awaitable方法Task.Factory.StartNew(async () =>
{
ListOfContacts = await _CouchModel.GetConatcsList ("Andy");
});