The following program hangs on the DoTheStuff().Wait();
line, if running as a Console application:
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);
}
}
}
It works just as expected though, if you comment out the new Form();
line. (Runs for 1sec, then quits).
How can I keep the expected behaviour and still have a Form instance?
Now, some background if you are interested:
I have an application which is hosted as a windows service (as console when testing locally).
It requires to have access to the SystemEvents.TimeChanged
event.
However, as per the documentation, this only works when having a windows Form (thus not in a service or console app). A workaround is presented in the linked documentation, and consists of creating a hidden form.
Unfortunately, the program now completely freezes instead, which is caused by the combination of await and having a Form
instance.
So how on earth can I still have the expected async/await behaviour while accessing the SystemEvents.TimeChanged
event?
Thanks to help below, here comes modified code which works without freeze:
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);
}
}
}
In my program, I need to use "SynchronizationContext.SetSynchronizationContext(null);", since the threadpool should be used for awaiting tasks. I don't think that is a good practice, since Form obviously initialized it for a reason. But running the form hidden without user input (it is a service!), and can't see any harm right now.
The documentation feels a bit incomplete, with MS not even mentioning the issue that may arise using the example 2 (await/async implicitly changes behaviour when instantiating a Form).