Cannot use AutoResetEvent.WaitOne() and Thread.Sleep in STAThread

726 views Asked by At

In my program, the main function starts a background thread which creates an object that I need in the UI thread (uses Windows Forms, thus marked [STAThread]).

Simplified code:

internal static MyDependencyInjectionKernel kernel;
internal static readonly object kernelLock = new object();
internal static AutoResetEvent kernelReadyEvent = new AutoResetEvent(false);

private static void BackgroundThread()
{
    kernel = new MyDependencyInjectionKernel();
    kernel.Inject(this);
    kernelReadyEvent.Set();
}

[STAThread]
public static void Main(string[] args)
{
    var backgroundThread = new Thread(new ThreadStart(BackgroundThread));
    backgroundThread.IsBackground = true;
    backgroundThread.Start();

    // Wait for background thread to create the object
    bool res = kernelReadyEvent.WaitOne();

    lock(kernelLock)
        Debug.Assert(kernel != null);

    // ...

    // Background thread still running here and doing other things (unimportant)
    Application.Run(new MainForm()); // <-- MainForm wants to use "kernel" field
}

However, res becomes false and the field kernel remains null in the main thread, even if I set a breakpoint at the lock statement. Also, using Thread.Sleep in the Main function would return immediately, without sleeping.

So it seems to me that probably [STAThread] puts restrictions to these methods?! Is that true, and what is a good way to circumvent this? In my case, I could probably mark the main thread as non-STA and then run an STA thread later on (did not try that yet), but is there a general solution?

0

There are 0 answers