C#-代码处理顺序-奇怪的行为
我有以下按钮单击事件:C#-代码处理顺序-奇怪的行为,c#,winforms,C#,Winforms,我有以下按钮单击事件: private void btnRun_Click(object sender, EventArgs e) { label1.Visible = true; if (SelectDatabase()) { if (string.IsNullOrEmpty(txtFolderAddress.Text)) MessageBox.Show("Please selec
private void btnRun_Click(object sender, EventArgs e)
{
label1.Visible = true;
if (SelectDatabase())
{
if (string.IsNullOrEmpty(txtFolderAddress.Text))
MessageBox.Show("Please select a folder to begin the search.");
else
{
if (cbRecurse.Checked == false || Directory.GetDirectories(initialDirectory).Length == 0)
{
CheckSingleFolder();
}
else
{
CheckSingleFolder();
directoryRecurse(initialDirectory);
}
}
}
}
实际上,它会进行一些检查,然后启动一些目录递归来查找特定的文件。但是,使标签可见的第一行代码直到目录被递归之后才会出现?有人知道为什么会这样吗
谢谢。您的整个方法当前作为一个阻塞单元运行-添加一个作为解决方案,但实际上您应该在后台线程中执行这种处理,即使用后台工作线程。代码在绘制用户界面的同一线程上执行。因此,在代码执行时,不会重新绘制UI。按钮单击代码完成后,UI将重新绘制,并且
label1
将以不可见的方式绘制
例如,您可以使用
Task
或BackgroundWorker
将代码移动到单独的线程中。但是,您不能直接从其他线程设置UI属性,因此您需要小心地从UI线程设置UI属性,或者注意如何从其他线程更新GUI。您在UI线程内完成所有操作,这是一个非常糟糕的主意-UI无法更新,对事件等做出反应,直到完成
您应该使用后台线程,并使用进度等更新UI,或者使用
基本上,WinForms中有两条黄金规则(与WPF/Silverlight类似):
- 不要做任何可能在UI线程中花费大量时间的事情
- 不要从UI线程以外的任何线程中接触任何UI元素
label1.Update()
更好的解决方案是将耗时的代码移动到线程(Backgroundworker) 哎哟。Application.DoEvents是一种黑客行为——这段代码不应该在UI线程上执行,而且是一种非常危险的黑客行为。我很高兴你补充了这一澄清;你险些被我投了一票有太多的答案提出了考虑不周的建议,无法使用
应用程序。DoEvents
。如果函数保存表单,请尝试刷新表单,可能会有所帮助<代码>form1.refresh()代码>等待新线程完成的最佳方式是什么?我有另一个方法,它必须等待递归完成。如果我使用一个单独的线程,然后使用while(thread.isalive){}之类的东西,它显然会阻塞线程,直到新线程完成。你推荐什么?谢谢。@Darren:让文件处理代码封送一个对UI线程的调用,调用以后需要继续的任何方法(例如重新启用按钮等)。非常感谢。例如,我只是简单地使用了一些东西:btnRun.Invoke((MethodInvoker)delegate{//Run Method})@达伦:是的,那类事情。就我个人而言,我更喜欢使用BeginInvoke
,除非您真的需要工作线程来阻止,但这是一个次要问题:)