Reputation: 1114
I am trying to save program state if user closes the program or initiates shutdown while program is still running but in this case the Task is not awaited and program terminates during writing settings leading to file corruption. How do I do it without creating an additional synchronous method for saving?
private async void Window_Closed(object sender, EventArgs e)
{
await programState.Save();
}
//from programState class
private async Task Save()
{
var state = JsonConvert.SerializeObject(progState, Formatting.Indented);
using (FileStream stream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read, 4096, FileOptions.Asynchronous | FileOptions.SequentialScan))
{
using (var sw = new StreamWriter(stream))
await sw.WriteAsync(state).ConfigureAwait(true);
}
}
Upvotes: 2
Views: 64
Reputation: 81513
There is no need to use the streams async
methods in this case, just use the regular StreamWriter.Write
on a synchronous path (i.e don't use the async and await pattern).
However, if you really had a need to use the async and await pattern from an event like Window_Closed
and it needed to be waited on (still knowing there is no good reason for it in this case), you will have to remove the async void
on Window_Closed
event; offload the work; then wait for it (not recommended)
private void Window_Closed(object sender, EventArgs e)
{
Task.Run(() => programState.Save()).Wait();
}
Note : Running asynchronous code synchronously usually leads to deadlocks in UI frameworks because of the way the continuations work with the MessagePump and Dispatchers. In this case you are offloading the async
work to the thread-pool and negating the deadlock via a sacrificial thread. In short, don't do it, just save to the stream synchronously
Upvotes: 1