Wpf 从ViewModel异步调用DAL

Wpf 从ViewModel异步调用DAL,wpf,architecture,mvvm-light,data-access-layer,Wpf,Architecture,Mvvm Light,Data Access Layer,我正在使用MVVM light构建复合WPF应用程序。我有使用MEF将ViewModels注入其中的视图: DataContext = App.Container.GetExportedValue<ViewModelBase>( ViewModelTypes.ContactsPickerViewModel); 目前,我有一些性能问题。一切都很慢。 我有两种相关的问题 异步调用DAL方法的正确方法是什么(访问我的couchdb)?等待/异步?任务?因为

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

DataContext = App.Container.GetExportedValue<ViewModelBase>(
                ViewModelTypes.ContactsPickerViewModel);
目前,我有一些性能问题。一切都很慢。 我有两种相关的问题

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

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

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

    _coucmodel.GetConcatcsListAsync(“Andy”)

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

    List<ContactInfo> ContactsList = e.Resuls; 
    
    List contacts List=e.results;
    
    ContactsList绑定到UC1中DropDownList框的ItemsSource。同样的情况也发生在UC2中。因此,我最终得到了两个完全相同的DB调用。 另外,如果我转到屏幕B,在那里我有UC1,我将再次调用DB,当我从屏幕A转到屏幕B时

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

    谢谢。

    广告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;
        }
    }
    
    Edit2:

    正在任务内调用可等待的方法:

    Task.Factory.StartNew(async () => 
    {
        ListOfContacts = await _CouchModel.GetConatcsList ("Andy");
    });
    

    例如,使用任务而不是异步有什么好处?您是否有实施此类数据库服务的示例?基本上,DatabaseService只是DB周围的另一个缓存,不是吗?我已经编辑了我的答案。异步/等待使用任务。我的意思是不同的-您可以使方法同步,然后异步调用它们(无论何时需要)创建任务,或者使它们异步并使用wait(但也需要使调用方法异步)。好的,谢谢。但我还是不懂wait/async的东西。我怎样才能使我的方法值得期待?因为目前我正在尝试:如果(_friendList.Count==0){//调用DAL以获取它等待任务。运行(()=>_manager.GetFriendList(name));},但它不起作用,我已经修改了我答案中的那一行。到底什么不起作用?感谢您一直支持我,您可以演示如何从ViewModel调用GetConcatcsList吗?ListOfContacts=wait_CouchModel.GetConatcsList(“Andy”);-告诉我只能在异步方法中使用wait。但我不想让ViewModel的构造函数成为异步的。这行不通。
    Task.Factory.StartNew(() => 
    {
        var result = dbService.GetContactsList("Andy");
    });
    
    Task.Factory.StartNew(async () => 
    {
        ListOfContacts = await _CouchModel.GetConatcsList ("Andy");
    });