【问题标题】:How should I synchronize between threads?我应该如何在线程之间同步?
【发布时间】:2011-11-15 14:45:10
【问题描述】:

考虑以下应用架构:

UI(视图)线程创建一个 ViewModel。

ViewModels 构造函数请求业务逻辑对象(提供者)开始从存储中检索数据。

它通过订阅提供者的 DataRecieved 事件并调用 StartRetrievingData() 方法来实现。

Provider 在 StartRetrievingData() 方法体中创建一个后台线程,循环获取数据并在循环体中引发 DataRecieved 事件,将实际数据对象作为自定义 EventArgs 公共字段传递。

链接到 DataRecieved 事件的 ViewModel 方法,然后更新绑定到该 UI 元素的 observableCollection。

问题是:

MVVM 实现之类的架构一切正常吗?

我应该在什么时候进行线程同步,即调用 Deployment.Current.Dispatcher 来调度源自后台线程的调用以更新 UI?

【问题讨论】:

    标签: c# .net multithreading architecture mvvm


    【解决方案1】:

    我个人会处理您的 ViewModel 中的所有同步要求。

    如果 View 正在构建 ViewModel,TPL 提供了一个很好的机制:

    TaskFactory uiFactory;
    
    public YourViewModel()
    {
         // Since the View handles the construction here, you'll get the proper sync. context
         uiFactory = new TaskFactory(TaskScheduler.FromCurrentSynchronizationContext());
    }
    
    // In your data received event:
    private items_DataReceived(object sender, EventArgs e)
    {
        uiFactory.StartNew( () =>
        {
            // update ObservableCollection here... this will happen on the UI thread
        });
    }
    

    这种方法的好处是您不必将 WPF 相关类型(例如 Dispatcher)拉入您的 ViewModel 层,而且它工作得非常干净。

    【讨论】:

    • 非常感谢。承认这一点我可能应该感到可耻,但在您回答之前,我不知道 TPL 在 .Net 中的存在。我的项目仍然在 Silverlight for Windows Phone 上,因此我将无法使用它。据我所知,便携式 TPL 不支持 TaskFactory。
    • @Maxim: Portable TPL 确实支持这一点 - 但你必须获得 TaskScheduler,并将其明确地传递给 StartNew 方法......不幸的是,它不允许你使用自定义调度程序(不知道为什么 - 但现在 API 中缺少)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-14
    • 2015-02-28
    • 2018-04-27
    • 2011-05-05
    • 1970-01-01
    • 2015-04-16
    • 2014-11-02
    相关资源
    最近更新 更多