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