我在.NET 4.0应用程序中使用Modern UI for WPF模板,其中一个页面需要在导航回另一个页面之前执行异步命令。同时,在运行命令时必须解锁UI线程。如果我这样做:
a_d
OnNavigatingFrom在导航回来之前等待,但在此期间UI被阻止。
有关如何在不同的上下文中执行异步代码并使OnNavigatingFrom运行"同步"?
的任何想法编辑:有一个similar thread有一个解决方法,没有确定的答案。
答案 0 :(得分:2)
以下是您需要做的事情:
public void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
// Fire and forget.
Task.Run(() => MyCommandAsync());
}
以上是一种即发即弃的方法,而是首选使用async
和await
:
public async void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
await MyCommandAsync();
}
答案 1 :(得分:1)
一个页面需要在导航回另一个页面之前执行异步命令
这就是问题所在。用户界面不是异步的,句点。在UI正在进行转换时,您无法将异步操作粘贴到混合中。
以这种方式思考:作为用户,如果您决定导航回来,并且网络打嗝或某些东西在程序中冻结几秒钟同时导航回来,这会带来糟糕的用户体验, 对?用户界面无法在更新期间等待异步工作。
您可以做的是在允许用户之前执行工作。例如,您可以捕获用户导航的意图,并显示某种类型的"请等待"操作进行时的UI,然后在操作完成后执行实际导航。
答案 2 :(得分:0)
仅await
Task
而不是.Wait()
。
请参阅Using async-await on .net 4了解如何在.NET 4.0中等待
答案 3 :(得分:0)
使用 OnNavigatingFrom 来完成您的工作。 e.Cancel 阻止回归。操作完成后使用Frame.GoBack()。
protected override async void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
if (Current.HasModifications())
{
e.Cancel = true;
await Current.Save().ContinueWith((t) =>
{
//Go Back after the Operation has finished
Frame.GoBack();
}, TaskScheduler.FromCurrentSynchronizationContext());
}
else
{
base.OnNavigatingFrom(e);
}
}