Caliburn Micro:确保在关闭应用程序之前调用所有 OnDeactivates

Caliburn Micro: Ensure that all OnDeactivates were called before app's shutdown

我有一个 WPF/Caliburn 应用程序,它有一个 ShellView,其中包括 TabControl,其中每个 TabItem 对应于个人 ViewModel(它们都继承 Screen).
其中一些 ViewModelsOnDeactivate 中实现了处理逻辑:

protected override void OnDeactivate(bool close)
{
    if (close)
        _disposeList.Dispose();

    base.OnDeactivate(close);
}

ShellViewModel 覆盖 TryClose

public override async void TryClose(bool? dialogResult = default(bool?))
{
    // some dispose logic here
    base.TryClose(dialogResult);
    await Task.Run(() =>
    {
        // show closing message for 2 sec
        using (StartBusy(ViewModelBusyReason.Closing))
        {
            Thread.Sleep(2000);
        }
    });
    Application.Current.Shutdown();
    // Environment.Exit(0);
}

当应用程序关闭时,它仅在 1 或 2 个虚拟机上调用 OnDeactivate,然后应用程序关闭。
如何保证 OnDeactivate 在应用关闭前在所有 VM 上被调用?
我尝试在 TryClose 中添加 Sleep,但没有成功。

还有:是否有一种规范的 Caliburn 方法可以在 ShellViewModel 上实现 TryClose
IE。我必须打电话给 Application.Current.Shutdown()Environment.Exit(0) 还是两者都不打电话?

ShellViewModel定义:

public class ShellViewModel : Conductor<Screen>.Collection.OneActive
{
    public ShellViewModel(/*some params here*/)
    {
        Items.Add(Bootstrapper.Resolve<ViewModelOne>());
        Items.Add(Bootstrapper.Resolve<ViewModelTwo>());
        Items.Add(Bootstrapper.Resolve<ViewModelThree>());
        // ...more VMs here
    }

ShellViewModelTryClose 方法调用每个子视图模型的 TryClose 方法:

//ShellViewModel:
public override void TryClose(bool? dialogResult = null)
{
    base.TryClose(dialogResult);
    //...
    foreach (var item in Items)
        item.TryClose();
}

此外,任何使用 IDisposable 字段的视图模型都应实现 IDisposable 接口:

public sealed class ViewModelTwo : Screen, IDisposable
{
    ...

    public override void TryClose(bool? dialogResult = null)
    {
        Dispose();
        base.TryClose(dialogResult);
    }

    public void Dispose()
    {
        _disposeList?.Dispose();
    }
}

好的,这是我最终想出的解决方案:

// ShellViewModel
public override void TryClose(bool? dialogResult = default(bool?))
{
    _disposeList.Dispose();

    while (Items.Any())
       DeactivateItem(Items.First(), true);

    base.TryClose(dialogResult);
    Application.Current.Shutdown();
}

并在每个单独的 VM 中覆盖 OnDeactivate

protected override void OnDeactivate(bool close)
{
    _disposeList.Dispose();
    base.OnDeactivate(close);
}