DoTheStuff().Wait();
如果作为控制台应用程序运行,则以下程序挂起:
namespace Test
{
using System.Threading.Tasks;
using System.Windows.Forms;
class Program
{
static void Main(string[] args)
{
new Form();
DoTheStuff().Wait();
}
private static async Task DoTheStuff()
{
await Task.Delay(1000);
}
}
}
如果您注释掉该new Form();
行,它会按预期工作。(运行 1 秒,然后退出)。
我怎样才能保持预期的行为并且仍然有一个 Form 实例?
现在,如果您有兴趣,请提供一些背景知识:
我有一个作为 Windows 服务托管的应用程序(在本地测试时作为控制台)。
它需要有权访问该SystemEvents.TimeChanged
事件。
但是,根据文档,这仅在具有 Windows 窗体时有效(因此不适用于服务或控制台应用程序)。链接文档中提供了一种解决方法,包括创建隐藏表单。
不幸的是,程序现在完全冻结了,这是由 await 和拥有Form
实例的组合引起的。
那么在访问SystemEvents.TimeChanged
事件时,我到底如何才能拥有预期的异步/等待行为呢?
感谢下面的帮助,这里有修改后的代码,它可以在没有冻结的情况下工作:
namespace Test
{
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
class Program
{
static void Main(string[] args)
{
new Thread(() => Application.Run(new Form())).Start();
// SynchronizationContext.SetSynchronizationContext(null);
DoTheStuff().Wait();
}
private static async Task DoTheStuff()
{
await Task.Delay(1000);
}
}
}
在我的程序中,我需要使用“SynchronizationContext.SetSynchronizationContext(null);”,因为线程池应该用于等待任务。我认为这不是一个好习惯,因为 Form 显然是出于某种原因对其进行了初始化。但是在没有用户输入的情况下运行隐藏的表单(它是一项服务!),现在看不到任何伤害。
文档感觉有点不完整,MS 甚至没有提到使用示例 2 可能出现的问题(await/async 在实例化表单时隐式更改行为)。