I've added a splash-screen form to a C# WinForms application to display while the application is being initialized/checking for updates. I'm using Squirrel.Windows to check for updates in Program.cs.
After adding the splash-screen, a call to Task.WaitAll in Main() never returns. This call worked as I expected before adding the splash-screen.
What can I do to ensure that the task completes in Main() while the splash-screen is displayed in the foreground?
Working example:
static void Main()
{
try
{
using (var mgr = new UpdateManager("xxxx"))
{
var task = mgr.UpdateApp();
task.RunSynchronously();
Task.WaitAll(task);
Console.WriteLine(task.Status);
}
}
catch (Exception ex)
{
logger.Debug(ex.Message);
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new XForm());
}
Non-working example:
static void Main()
{
var ss = new SplashScreen();
Application.Run(ss);
try
{
using (var mgr = new UpdateManager("xxxx"))
{
var task = mgr.UpdateApp();
task.RunSynchronously();
Task.WaitAll(task);
Console.WriteLine(task.Status);
}
}
catch (Exception ex)
{
logger.Debug(ex.Message);
}
ss.Close();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new XForm());
}
I've read a bunch of SO posts describing lock-up on Task.WaitAll, but I can't find a direct explanation of the phenomena I'm seeing here i.e.
Synchronously waiting for an async operation, and why does Wait() freeze the program here
How would I run an async Task<T> method synchronously?
I did try the suggestion of calling task.RunSynchronously() but it seemed to make no difference.
You can solve this problem using one of two approaches.
Change to C# 7.1 and make your main method ASYNC Right click project > Build > Advanced > C# latest Minor Version
static async Task Main()
{
try
{
using (var mgr = new UpdateManager("xxxx"))
{
await mgr.UpdateApp();
}
}
catch (Exception ex)
{
logger.Debug(ex.Message);
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new XForm());
}
Or
If UpdateApp returns a value
use .Result
If UpdateApp does not return a value
use .Wait()
static void Main()
{
try
{
using (var mgr = new UpdateManager("xxxx"))
{
mgr.UpdateApp().Wait();
}
}
catch (Exception ex)
{
logger.Debug(ex.Message);
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new XForm());
}