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?