I have a UWP app that lets users create and modify text documents. I'm having a hard time getting the save mechanism to work with the app suspend/resume lifecycle.
Here is what I have:
- All disk access is done on a separate background thread to keep the UI responsive
- That background thread also serializes all disk access to ensure that at all times, only one read or write operation takes place
- Before and after a document is saved, the UI is updated to indicate that a save is in progress. This is scheduled on the UI thread via
Dispatcher.RunAsync()
When the app is being suspended:
- On suspending, I must save the document one final time to ensure that all changes are on disk (the app may get terminated while suspended)
- So I request an
ExtendedExecutionSession
- I schedule one final save operation on my queue
- I then wait for the queue to process all pending disk access operations
- Finally, I mark the extended execution session as completed
My problem:
- An already scheduled save operation completes its disk access and then tries to update the UI on the main thread via
Dispatcher.RunAsync()
. The background queue waits for this task to finish, but it never does, because by that time, the UI thread has been stopped already.
→ So my final save operation is never executed, because the background queue is stuck waiting to update the UI.
Here's a flow diagram:
A few questions that arise:
- When exactly is the UI thread stopped while an app is being suspended? Only when it's idle or "right in between" anything? I.e. if I scheduled a block via
Dispatcher.RunAsync()
, will this at least finish or "freeze"? - Is there a way for me to check if the UI thread of the current window is already stopped so that I know that I must not access it anymore in my background file access thread?
- Which threads are stoppend and when, while an app is being suspended?
- Is my background file access thread also at risk at being stopped while the app is being suspended?
To summarize the problem:
While the app is being suspended, I must ensure that I wait for a potentially pending disk access on a background thread to finish before I finally save the document one more time in case my app gets terminated later on.
Dispatcher.RunAsync()
when handling the event? Won't this in turn block my background queue again? – Continuate