C# 从后台操作导航
我的应用程序中有一个显示的页面,我想执行一个潜在的长时间运行的后台操作。此操作正在进行时,应显示另一个视图,完成后,应将该区域导航回其以前的视图。如果出现任何问题,导航应该转到其他视图 为了说明这一点,假设我有一些类,并在其构造函数中设置一个ICommand:C# 从后台操作导航,c#,wpf,prism,C#,Wpf,Prism,我的应用程序中有一个显示的页面,我想执行一个潜在的长时间运行的后台操作。此操作正在进行时,应显示另一个视图,完成后,应将该区域导航回其以前的视图。如果出现任何问题,导航应该转到其他视图 为了说明这一点,假设我有一些类,并在其构造函数中设置一个ICommand: SomeAction = new DelegateCommand(() => { _regionManager.RequestNavigate("MyTarget", nameof(SomeProgressPage));
SomeAction = new DelegateCommand(() =>
{
_regionManager.RequestNavigate("MyTarget", nameof(SomeProgressPage));
Task.Run(() =>
{
DoSomeWork();
});
});
任务本身与潜在的长期运行相关;一旦完成,它应该导航到一个有条件的目的地
private void SomeWork()
{
try
{
// Do Work
// ...
// Return when done.
_regionManager.RequestNavigate("MyTarget", nameof(SomePage));
}
catch
{
_regionManager.RequestNavigate("MyTarget", nameof(SomeErrorPage));
}
}
虽然我可以在调试中逐步完成这一过程,并且不会在调试过程中遇到任何错误,但当从另一个线程调用RequestNavigation时,它似乎没有任何效果,也不会引发异常。我确实导航到“SomeProgressPage”,任务确实在运行,并且根据其结果,可以跟踪执行到RequestNavigation,然后什么也不做
我还尝试通过以下事件执行此导航:
eventAggregator.GetEvent<NavigationRequestEvent>().Subscribe(x =>
{
regionManager.RequestNavigate(x.Target, x.Destination, x.Parameters);
}, ThreadOption.UIThread);
eventAggregator.GetEvent().Subscribe(x=>
{
regionManager.RequestNavigate(x.Target,x.Destination,x.Parameters);
},ThreadOption.UIThread);
在这种情况下,发布事件时甚至不会调用订阅服务器
我在谷歌上找不到任何可靠的资源来处理这个问题,也没有通过Prism连接到源代码和调试;在使用Prism时,如何最好地实现这类功能 问题是,任务AggregatedException处理程序会吞没在未等待的任务中抛出的异常。通过检查task.Exception属性,可以访问任务引发的异常。您还可以执行以下操作:
Task.Run(() =>
{
//DoSomeWork();
})
.ContinueWith((t) =>
{
// Return when done.
_regionManager.RequestNavigate("MyTarget", nameof(SomePage));
})
.ContinueWith((t) =>
{
_regionManager.RequestNavigate("MyTarget", nameof(SomeErrorPage));
}, TaskContinuationOptions.OnlyOnFaulted);
第二个ContinueWith仅在任务出现故障时启动(意味着任务引发了异常)。如果要从另一个线程打开新窗口,则需要调用当前调度程序
private void SomeWork()
{
try
{
// Do Work
// ...
// Return when done.
App.Current.Dispatcher.Invoke((Action)delegate
{
_regionManager.RequestNavigate("MyTarget", nameof(SomePage));
});
}
catch
{
App.Current.Dispatcher.Invoke((Action)delegate
{
_regionManager.RequestNavigate("MyTarget", nameof(SomeErrorPage));
});
}
}