.Net奇怪的锁定语义再次困扰着我。

我正在启动一个线程,子线程又会启动一个表单。父线程应等待,直到创建表单。

我的第一次尝试是使用Monitor来监视Form变量:

private void OpenForm()
{
    if (FormThread == null)
    {
        Monitor.Enter(Form);
        FormThread = new Thread(FormStub);
        FormThread.SetApartmentState(ApartmentState.STA);
        FormThread.Start();
        Monitor.Wait(Form);
        Monitor.Exit(Form);
    }
}

private void FormStub()
{
    Form = new ConnectorForm();
    Monitor.Enter(Form);
    Monitor.PulseAll(Form);
    Monitor.Exit(Form);
    Application.Run(Form);
}

...这引发异常。 Monitor.Enter()失败,因为Form == null。

我可以很容易地创建一个虚拟整数或其他东西(实际上我想我可以使FormThread变量无效),但是我想知道是否有一个更优雅的解决方案。

最佳答案

对于这种情况,更好的同步原语:

private ManualResetEvent mre = new ManualResetEvent(false);

private void OpenForm()
{
    if (FormThread == null)
    {
        FormThread = new Thread(FormStub);
        FormThread.SetApartmentState(ApartmentState.STA);
        FormThread.Start();
        mre.WaitOne();
    }
}

private void FormStub()
{
    Form = new ConnectorForm();
    mre.Set();
    Application.Run(Form);
}

09-11 22:22