在我的程序中,main函数启动一个后台线程,它在UI线程中创建一个我需要的对象(使用Windows Forms,因此标记为[STAThread])。
简化代码:
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
}
但是,res
变为false,并且字段kernel
在主线程中保持为null,即使我在lock语句中设置了断点。此外,在Thread.Sleep
函数中使用Main
会立即返回,而不会休眠。
所以在我看来,[STAThread]
可能会对这些方法施加限制?!这是真的,有什么好办法来规避这个?在我的情况下,我可能将主线程标记为非STA,然后稍后运行STA线程(还没有尝试),但是有一般解决方案吗?