我是C#的新手,我使用的是Windows窗体
我在BackgroundWorker中做了一些工作有问题。
我有2个表单(Form1
和Form2
)和3 User Controls
UC1
,UC2
和UC3
。
Form1
只有一个显示button
Form2
的{{1}}。
Form2
有4 buttons
(Btn_ShowUC1
,Btn_ShowUC2
,Btn_ShowUC3
和Button_Close
)和3 BackgroundWorkers
。
我要做的是:当我点击button1
中的Form1
时,Form2
会显示,然后我想显示相关的User control
并隐藏当我点击Form2
中的任何按钮时休息。例如:点击Btn_ShowUC1
user control1
显示并隐藏其余内容,点击Btn_ShowUC2
user control2
显示并隐藏其余内容,依此类推。现在在UI中显示和隐藏user controls
有时会使Form2
冻结,因此我使用BackgroundWorkers来显示/隐藏user control
进程。
我正在为每个相关性按钮使用3 BackgroundWorkers
,以防一个BackgroundWorker
忙于执行显示/隐藏过程。
在Form1中:
Form2 f2 = new Form2();
private void button1_Click(object sender, EventArgs e)
{
f2.ShowDialog();
}
在Form2中:
UserControl CurrentUserControl;
UserControl1 uc1 = new UserControl1();
UserControl2 uc2 = new UserControl2();
UserControl3 uc3 = new UserControl3();
public Form2()
{
InitializeComponent();
Controls.Add(uc1);
Controls.Add(uc2);
Controls.Add(uc3);
}
private void Form2_Load(object sender, EventArgs e)
{
foreach (Control ctrl in this.Controls)
{
if (ctrl is UserControl)
{
ctrl.Visible = false;
}
}
uc1.Visible = true;
}
private void Btn_ShowUC1_Click(object sender, EventArgs e)
{
CurrentUserControl = uc1;
backgroundWorker1.RunWorkerAsync();
}
private void Btn_ShowUC2_Click(object sender, EventArgs e)
{
CurrentUserControl = uc2;
backgroundWorker2.RunWorkerAsync();
}
private void Btn_ShowUC3_Click(object sender, EventArgs e)
{
CurrentUserControl = uc3;
backgroundWorker3.RunWorkerAsync();
}
private void Button_Close_Click(object sender, EventArgs e)
{
close();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
foreach (Control ctrl in this.Controls)
{
if (ctrl is UserControl)
{
ctrl.Visible = false;
}
}
CurrentUserControl.Visible = true;
}
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
foreach (Control ctrl in this.Controls)
{
if (ctrl is UserControl)
{
ctrl.Visible = false;
}
}
CurrentUserControl.Visible = true;
}
private void backgroundWorker3_DoWork(object sender, DoWorkEventArgs e)
{
foreach (Control ctrl in this.Controls)
{
if (ctrl is UserControl)
{
ctrl.Visible = false;
}
}
CurrentUserControl.Visible = true;
}
当Form2
加载usercontrol1
出现时,当我点击任何任何按钮时,相关的用户控件都显示出来并且每件事情都运行良好。但是,当我关闭form2
然后再次打开它并点击任何按钮时,user controls
没有显示和Form2
冻结,它会抛出错误,说“此backGroundWorker当前正忙,不能同时运行多个任务“
为什么我有这个错误?我的意思是我正在使用3种不同的backGroundWorkers
。
请注意,这是我在项目中的所有代码。
任何人都知道如何解决它?我的意思是当我点击任何按钮而不冻结表单时,我想在单独的线程中显示/隐藏用户控件。 我会很高兴听到任何不同的想法。 谢谢
答案 0 :(得分:1)
虽然这可能是试用BackgroundWorker
的好方法,但你使用的却是错误的。 UI线程您通过首先运行应用程序已经使用的那个,应该负责显示/隐藏控件以及任何其他UI相关任务。因此,此BGW
实际上是多余的,只需在for-loop
事件中执行Button_Click
即可。
通过将True
或False
分配给Visibility
属性,您实际上将0从0更改为1。您的机器执行此操作所需的时间和精力是不存在的。 BGWs
用于执行长时间运行的任务,单独使用新线程的开销会使设置属性的整个操作浪费资源而完全没必要。
如果您仍然希望这样做,要了解某些内容或其他内容,您需要delegate this work to the UI thread。
发生这种情况是因为您无法从UI线程的任何其他线程访问UI。
这实际上也意味着你的BGW
会变得更加浪费资源,因为你实际上创建了一个新线程,无论如何都要在UI线程上做一些事情。
然后,从后台线程,你告诉UI线程(从你开始的地方)无论如何都要执行工作。