我有一个UWP应用程序,允许用户创建和修改文本文档。我很难让保存机制与app暂停/恢复生命周期一起使用。
这就是我所拥有的:
Dispatcher.RunAsync()
暂停应用时:
ExtendedExecutionSession
我的问题:
Dispatcher.RunAsync()
更新主线程上的UI。后台队列等待此任务完成,但它永远不会,因为到那时,UI线程已经停止。→因此我的最终保存操作永远不会执行,因为后台队列等待更新UI。
这是一个流程图:
出现了一些问题:
Dispatcher.RunAsync()
安排了一个阻止,这至少会完成或者#34;冻结"?总结问题:
当应用程序被暂停时,我必须确保我等待后台线程上可能正在挂起的磁盘访问才能完成,然后我再次保存文档,以防我的应用程序稍后终止。
答案 0 :(得分:4)
这听起来太熟悉了!
我从您的问题中了解到,保存操作以更新UI结束,但由于它在后台线程中运行,因此除非您使用Dispatcher
进行安排,否则无法触及UI。只是为了可视化,您的代码看起来像这样:
public async Task SaveAsync()
{
// .. save to disk ..
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// update UI here
}
// Save Complete!
}
如果是这样,问题是UI更新是排队后台操作的一部分,如果UI更新或Dispatcher
本身阻止了任何内容,则在到达该行之前不会开始其他操作{ {1}},如果//Save Complete!
从未执行您的操作,则永远不会发生。
不要考虑使用UI更新的保存操作,而是尝试公开将触发UI更新的事件。例如:
Dispatcher
您的视图可以将处理程序附加到这些事件并显示/隐藏相应的视觉效果,而您的暂停处理程序可以安全地调用public event EventHandler SaveStarted;
public event EventHandler SaveCompleted;
public async Task SaveAsync()
{
SaveStarted?.Invoke(this, EventArgs.Empty);
// .. save to disk ..
SaveCompleted?.Invoke(this, EventArgs.Empty);
}
方法而无需担心UI。
当视图为SaveAsync()
时,请确保分离这些事件处理程序。在提出这些事件时,您的保存操作不会阻止队列。
更新1
是的,您的事件处理程序必须使用Unloaded
:
Dispatcher
因为处理程序被强制返回public void OnSaveCompleted(object sender, EventArgs e)
{
Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
// update UI here...
}
}
,所以它不会阻止后台线程。
更新2
听起来你有一些紧密耦合。您需要重新设计应用程序,使文本文档逻辑位于单独的项目中。我总是在 .Net Standard 项目中编写代码,强制所有用户界面输出。该项目将不允许任何UI代码,从而保持您的逻辑清洁和分离。
如果您的所有代码都位于UWP项目中,那么开始包含视图逻辑,XAML控件以及在您的情况下,应用程序中与演示无关的void
非常容易。< / p>
在您的情况下,您需要弄清楚如何使文本文档逻辑成为文档状态的所有者,而不是UI。 Dispatcher
只能由拥有hasChanges
的相同逻辑修改。如果在UI操作期间某些东西中断/阻塞/失败/等并且它永远不会成功到文本文档,那么它是一个不完整的操作,不应该是文档的一部分,也不应该担心文档的责任什么时候暂停&amp;保存到磁盘。
如果UWP在其中一项操作中因任何原因导致您的应用程序被杀,那么它就消失了。您的下一个任务是弄清楚当应用程序再次唤醒时如何恢复此操作。