C# 挂起Windows应用商店应用程序:调用MvxSuspensionManager.SaveAsync()时出错

C# 挂起Windows应用商店应用程序:调用MvxSuspensionManager.SaveAsync()时出错,c#,windows-runtime,mvvmcross,C#,Windows Runtime,Mvvmcross,我有一个使用MvvmCross的WinRT应用程序,我想在其中存储当前会话状态 在tha App.xaml.cs的OnLaunch方法中,我向悬架管理器注册了我的应用程序的内容框架: ... var setup = new Setup(_contentFrame); setup.Initialize(); var suspensionManager = Mvx.GetSingleton<IMvxSuspensionManager>() as MvxSuspensionManager

我有一个使用MvvmCross的WinRT应用程序,我想在其中存储当前会话状态

在tha App.xaml.cs的OnLaunch方法中,我向悬架管理器注册了我的应用程序的内容框架:

...
var setup = new Setup(_contentFrame);
setup.Initialize();

var suspensionManager = Mvx.GetSingleton<IMvxSuspensionManager>() as MvxSuspensionManager;
suspensionManager.RegisterFrame(_contentFrame, "FrameNav");
...         
这是由MvxSuspensionManager执行的。当我直接调用此函数时,它将失败并出现相同的错误

我知道WinRT框架导航堆栈只能在非复杂类型用作导航参数时序列化。但是我的应用程序崩溃了,即使我只是在第一页挂起

也许我用MvvmCross挂起的方法是错误的,或者我错过了一些正确设置的步骤


非常感谢您的帮助

我猜这不是您使用中的错误,而是“标准”悬架管理器的MvvmCross adaption中的某个错误,可能是保存的对象类型中的错误

MvvmCross中的
SuspendionManager
代码主要基于Windows8.0
Common
模板,用于
SuspendionManager
——但我记得在早期开发过程中有很多挫折(使用各种预览版本)使用
COMException
s,它经常返回诸如
unknown error
之类的无用消息

实际上,Windows 8暂停(到目前为止)在MvvmCross用户的优先级列表中并没有上升到很高的位置——因此,如果当前的调整需要添加或修复,我也不会感到惊讶(特别是当Windows进入8.1时,LayoutWarePage已被弃用)。MvvmCross中的加载/还原状态在许多应用程序中用于“内存中”缓存状态,但我个人没有将其用于从“暂停和关闭”终止状态恢复应用程序


如果你的应用程序需要这种保存到磁盘或从磁盘保存的工作暂停功能,那么我相信
MvxSuspensionManager
和相关的
MvxStorePage.SaveStateBundle
MvxStorePage.LoadStateBundle
代码只需稍加调试即可工作,我相信重要的方法都被标记为虚拟的,这样它们就可以很容易地被重写,但是。。。悲哀地我相信让它们工作可能是一次令人沮丧的调试体验,包括来自
COMException
的“未知错误”时刻有两个问题正在禁用悬架管理器。正如您所说,MvX使用复杂(ViewModelRequests)对象而不是字符串进行导航。您可以通过创建自己的ViewPresenter来解决此问题,它应该如下所示:

public class CustomViewPresenter : MvxStoreViewPresenter {
    //XXX: Holding a ref here because base class's ref to the frame is for some reason private.
    private Frame _curFrame;
    public CustomViewPresenter(Frame RootFrame) : base(RootFrame) {
        _curFrame = RootFrame;
    }

    public override void Show(MvxViewModelRequest request) {
        try {
            var requestTranslator = Mvx.Resolve<IMvxViewsContainer>();
            var viewType = requestTranslator.GetViewType(request.ViewModelType);

            var converter = Mvx.Resolve<IMvxNavigationSerializer>();
            var requestText = converter.Serializer.SerializeObject(request);

            _curFrame.Navigate(viewType, requestText);
        } catch (Exception exception) {
            MvxTrace.Trace("Error seen during navigation request to {0} - error {1}", request.ViewModelType.Name,
                           exception.ToString());
        }
    }
}

希望这一切都能在Mvx的未来版本中推出,这样我们就不必做这些后推了。

非常感谢您的支持。我的CustomPresenter实际上没有任何用处,这让我发疯:这个.OnViewCreate(req,()=>LoadStateBundle(e));在我的所有视图中。此解决方案现在已合并到MvvmCross中
Cirrious.MvvmCross.WindowsStore.Views.Suspension.MvxSuspensionManagerException "MvxSuspensionManager failed"
at Cirrious.MvvmCross.WindowsStore.Views.Suspension.MvxSuspensionManager.<SaveAsync>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at ****App.xaml.cs:line 129
System.Runtime.InteropServices.COMException "Unbekannter Fehler
"
at Windows.UI.Xaml.Controls.Frame.GetNavigationState()
at Cirrious.MvvmCross.WindowsStore.Views.Suspension.MvxSuspensionManager.SaveFrameNavigationState(Frame frame)
at Cirrious.MvvmCross.WindowsStore.Views.Suspension.MvxSuspensionManager.<SaveAsync>d__0.MoveNext()
Frame.GetNavigationState();
public class CustomViewPresenter : MvxStoreViewPresenter {
    //XXX: Holding a ref here because base class's ref to the frame is for some reason private.
    private Frame _curFrame;
    public CustomViewPresenter(Frame RootFrame) : base(RootFrame) {
        _curFrame = RootFrame;
    }

    public override void Show(MvxViewModelRequest request) {
        try {
            var requestTranslator = Mvx.Resolve<IMvxViewsContainer>();
            var viewType = requestTranslator.GetViewType(request.ViewModelType);

            var converter = Mvx.Resolve<IMvxNavigationSerializer>();
            var requestText = converter.Serializer.SerializeObject(request);

            _curFrame.Navigate(viewType, requestText);
        } catch (Exception exception) {
            MvxTrace.Trace("Error seen during navigation request to {0} - error {1}", request.ViewModelType.Name,
                           exception.ToString());
        }
    }
}
    protected override void OnNavigatedTo(NavigationEventArgs e) {
        var reqData = (string)e.Parameter;

        var converter = Mvx.Resolve<IMvxNavigationSerializer>();
        var req = converter.Serializer.DeserializeObject<MvxViewModelRequest>(reqData);

        this.OnViewCreate(req, () => LoadStateBundle(e));
    }
private readonly List<Type> _knownTypes = new List<Type>(); 
private readonly List<Type> _knownTypes = new List<Type>() { typeof(Dictionary<string, string>) };
    protected override Cirrious.MvvmCross.WindowsStore.Views.Suspension.IMvxSuspensionManager CreateSuspensionManager() {
        return new MyFixedSuspensionManager();
    }