【问题标题】:Non-ui blocking tasks with WPF/Caliburn使用 WPF/Caliburn 的非 ui 阻塞任务
【发布时间】:2015-10-15 07:14:48
【问题描述】:

我正在尝试从外部 API 获取一定数量的数据并将其填充到视图的列表中。我的设置类似于以下(摘录):

ShellView

<xctk:BusyIndicator IsBusy="{Binding IsBusy}">
    <ContentControl x:Name="ActiveItem" />
    ...

ShellViewModel

...
public bool IsBusy
{
    get { return _isBusy; }
    private set
    {
        _isBusy = value;
        NotifyOfPropertyChange();
    }
}

public void StartProgress()
{
    IsBusy = true;
}

public void StopProgress()
{
    IsBusy = false;
}

protected override void OnViewLoaded(object view)
{
    base.OnViewLoaded(view);
    // do some task
    ActivateItem(SomeOtherViewModel);
}

SomeOtherViewModel

public SomeOtherViewModel(IBusyIndicator busy)
{
  ....
}

protected override void OnViewLoaded(object view)
{
    base.OnViewLoaded(view);

    Task.Factory.StartNew(ACTION,
                    CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default)
                    .ConfigureAwait(true);
}

基本上,工作流程是这样的:

  1. 初始化Shell
  2. Shell -> OnViewLoaded
  3. 做一些后台工作
  4. 初始化SomeOtherViewModel (将IBusyIndicator 注入,即Shell 作为单例)
  5. SomeOtherViewModel -> OnViewLoaded
  6. 做其他后台工作,就像上面的例子一样

但是,当我启动应用程序时,直到所有内容都加载完毕,我才看到视图。有没有办法:

  • 仅当一切都可见时才执行操作 (WPF / Caliburn)
  • 在不阻塞 UI/视图模型更新的情况下执行 Task?

【问题讨论】:

    标签: c# wpf async-await task caliburn.micro


    【解决方案1】:

    如果您希望在 UI 中的可见性发生变化时发生某些事情,那么您应该在 UI 层中对其进行编码,根据您的用例在 Loaded 事件或 VisibilityChanged 上进行编码。

    如果您需要它来触发 ViewModel 上的操作,那么只需从 UI 中引用 ViewModel。这在 MVVM 中是可以接受的。

    public ViewModel ViewModel
    {
        get
        {
            return DataContext as ViewModel;
        }
    }
    
    public void OnLoaded()
    {
        ViewModel.DoThatThing();
    }
    

    为了弄清楚您的线程阻塞的原因,我需要查看完整的代码示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-07
      • 1970-01-01
      • 1970-01-01
      • 2015-11-06
      • 2012-01-16
      • 1970-01-01
      • 2012-09-29
      相关资源
      最近更新 更多