C# 后台工作程序在C中显示用户交互窗体时尝试暂停主线程#

C# 后台工作程序在C中显示用户交互窗体时尝试暂停主线程#,c#,backgroundworker,semaphore,windowsformshost,C#,Backgroundworker,Semaphore,Windowsformshost,我正在制作(尝试)一个类似于openFileDialogue的对话框,其中主线程的程序流暂停,直到OPF.ShowDialogue()函数在运行单独的线程时暂停 我有一个OpenFileDialogue\u Gui类,它使用信号量和后台工作程序 首先启动后台工作程序以生成具有必要用户界面的单独表单 然后信号量暂停主线程,直到用户单击后台线程窗体上的一个按钮 然后它释放信号量,并将结果发送回调用函数 理论上听起来不错,但有个问题。后台工作程序未显示其窗体,也不工作 代码如下: public cla

我正在制作(尝试)一个类似于openFileDialogue的对话框,其中主线程的程序流暂停,直到
OPF.ShowDialogue()
函数在运行单独的线程时暂停

我有一个
OpenFileDialogue\u Gui
类,它使用信号量和后台工作程序

首先启动后台工作程序以生成具有必要用户界面的单独表单

然后信号量暂停主线程,直到用户单击后台线程窗体上的一个按钮

然后它释放信号量,并将结果发送回调用函数

理论上听起来不错,但有个问题。后台工作程序未显示其窗体,也不工作

代码如下:

public class openfiledialogue_Gui
{
    Semaphore semStall = new Semaphore(0, 1);
    BackgroundWorker bck = new BackgroundWorker();

    public openfiledialogue_Gui()
    {
        bck.WorkerSupportsCancellation = true;
        bck.DoWork += Bck_DoWork;
        bck.RunWorkerCompleted += Bck_RunWorkerCompleted;
    }

    public enum enuResult { Ok, Cancel, _num };
    public enuResult ShowDialogue()
    {
        bck.RunWorkerAsync();
        semStall.WaitOne();
        return eResult;
    }

    enuResult eResult = enuResult.Cancel;

    void EventOk_click(object sender, EventArgs e)
        {
            eResult = enuResult.Ok;
            strFilename = "ok clicked";
            semStall.Release();
        }

    void EventCancel_click(object sender, EventArgs e)
        {
            eResult = enuResult.Cancel;
            strFilename = "cancel clicked";
            semStall.Release();
        }

    private void Bck_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){semStall.Release();}

    private void Bck_DoWork(object sender, DoWorkEventArgs e)
    {
        Form frmShow = new Form();
        Button btnOk = new Button();
        btnOk.Text = "ok";

        Button btnCancel = new Button();
        btnCancel.Text = "Cancel";

        btnOk.AutoSize
            = btnCancel.AutoSize
            = true;

        frmShow.Controls.Add(btnOk);
        frmShow.Controls.Add(btnCancel);

        frmShow.ControlBox = false;

        btnOk.Location = new Point(100, 25);
        btnCancel.Location = new Point(100, 75);

        btnCancel.Click += EventCancel_click;
        btnOk.Click += EventOk_click;
        frmShow.Show();

    }

    public string strFilename = "this is a test";
    public string Filename
    { 
    get { return strFilename; }
    }
}

有什么办法可以让它工作吗?

听起来你想做一个“模态形式”

var form = new MyModalForm();
form.ShowDialog();

这将“暂停”UI,直到您取消(或关闭)表单。

我通常在backgroundworker的报告进度中使用state对象将文本发送到主线程。然后在主线程中添加代码以显示表单。谢谢,但我尝试的是在backgroundworker显示表单时让调用表单暂停(与C#原生的OpenFileDialogue的方式相同)。不幸的是,现在一切都停滞了。你不能这样做!!!后台类与窗体位于不同的线程中。您必须在form类中创建一个Report Progress事件方法,然后从该事件打开对话框。您询问调用semStall.WaitOne()时遇到的死锁。这将挂起UI线程,防止RunWorkerCompleted事件被激活。但错误远不止于此。您必须严格在主线程上调用窗体的ShowDialog()方法。您不应该“暂停”主UI线程。这是个糟糕的设计。UI线程必须始终“自由流动”,以保持用户响应能力。BackgroundWorkers就是这样,他们在后台工作,这样主UI线程就不会阻塞。你需要重新考虑你的设计。哇!就是这样。这是我一直在寻找的一个神奇的词,当一直有ShowDialog()本机指令时,我试图将自己拧成一个结,使其工作。非常感谢。