为什么直接在 Main() 中启动表单时 Task.WaitAll 挂起?
Why does Task.WaitAll hang when a form is launched directly in Main()?
我已经向 C# WinForms 应用程序添加了启动屏幕表单,以便在应用程序 initialized/checking 进行更新时显示。我正在使用 Squirrel.Windows 检查 Program.cs 中的更新。
添加启动画面后,在 Main() 中调用 Task.WaitAll 永远不会 returns。在添加启动画面之前,此调用按我预期的方式工作。
当启动画面显示在前台时,我可以做些什么来确保任务在 Main() 中完成?
工作示例:
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());
}
非工作示例:
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());
}
我读过很多描述 Task.WaitAll 锁定的 SO 帖子,但我找不到对我在这里看到的现象的直接解释,即
Synchronously waiting for an async operation, and why does Wait() freeze the program here
How would I run an async Task<T> method synchronously?
我确实尝试了调用 task.RunSynchronously() 的建议,但似乎没有任何区别。
您可以使用以下两种方法之一解决此问题。
更改为 C# 7.1 并将您的主要方法设为 ASYNC
右键单击项目 > 构建 > 高级 > C# 最新次要版本
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());
}
或
如果 UpdateApp return 是一个值
使用.Result
如果 UpdateApp 没有return一个值
使用 .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());
}
我已经向 C# WinForms 应用程序添加了启动屏幕表单,以便在应用程序 initialized/checking 进行更新时显示。我正在使用 Squirrel.Windows 检查 Program.cs 中的更新。
添加启动画面后,在 Main() 中调用 Task.WaitAll 永远不会 returns。在添加启动画面之前,此调用按我预期的方式工作。
当启动画面显示在前台时,我可以做些什么来确保任务在 Main() 中完成?
工作示例:
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());
}
非工作示例:
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());
}
我读过很多描述 Task.WaitAll 锁定的 SO 帖子,但我找不到对我在这里看到的现象的直接解释,即
Synchronously waiting for an async operation, and why does Wait() freeze the program here
How would I run an async Task<T> method synchronously?
我确实尝试了调用 task.RunSynchronously() 的建议,但似乎没有任何区别。
您可以使用以下两种方法之一解决此问题。
更改为 C# 7.1 并将您的主要方法设为 ASYNC 右键单击项目 > 构建 > 高级 > C# 最新次要版本
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());
}
或
如果 UpdateApp return 是一个值
使用.Result
如果 UpdateApp 没有return一个值
使用 .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());
}