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