我的表单上有一个按钮,当点击它时会执行以下操作:
private void btnCheckSVN_Click(object sender, EventArgs e)
{
wait = new DevExpress.Utils.WaitDialogForm("Fetching File SVN Status",
"Please Wait");
wait.AutoSize = true;
wait.Visible = false;
bgwSVN.RunWorkerAsync();
wait.ShowDialog();
}
private void bgwSVN_DoWork(object sender, DoWorkEventArgs e)
{
e.Result = svn.SvnStatusEventArgsToDataTable(svn.CheckSVN(_localPath));
}
private void bgwSVn_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
DataTable dt = (DataTable)e.Result;
dt.DefaultView.Sort = "File ASC";
gdcSVN.DataSource = dt;
gdcSVNDefaultView.BestFitColumns();
xtcTabs.SelectedTabPageIndex = 1;
lblTotalFileCount.Text = dt.Rows.Count.ToString();
if (dt.Rows.Count == 0)
XtraMessageBox.Show("No files found.",
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
wait.Close();
}
通过这个操作顺序,您(显然)仍然可以看到MessageBox
后面的等待对话,我认为它看起来非常草率。
如果我切换IF语句和Close()
来电,我的WaitDialogForm
一半会因缺少更好的条款而消失。有一个空的矩形,红色的框架和一个巨大的X穿过它,然后在它顶部的MessageBox
作为它自己的形式。
这是我第一次搞乱任何类型的多线程或使用BackgroundWorker
对象,所以我确定我只是错过了一些非常愚蠢的东西,但我不知道是什么?
我尝试从此事件中完全删除MessageBox
,而是执行此操作:
wait.Close();
lblTotalFileCount.Text = dt.Rows.Count.ToString();
然后处理标签的TextChanged事件并检查它是否应该显示MessageBox然后......但我仍然用红色框得到相同的结果。
修改;另外,我注意到一个奇怪的事情。在表单加载时,lblTotalFileCount设置为0.当此方法运行并说它找到0个文件时,它会将lblTotalFileCount.Text重新设置为零...哪个不会触发TextChanged事件?我知道它已经设置为它已经存在的相同的东西,但它仍然在技术上改变了。我错过了什么,或者事件是否真的检查了那个条件并“跳过”它,如果是这样的话?我不得不将标签设置为空字符串而不是...但是说他们运行应用程序,它被设置为0,提醒他们,他们做了一些更改,再次运行...仍然是0,它不会提醒他们。
编辑2 ;我想也许如果我尝试在TextChanged事件中调用wait.Close(),如我在消息框出现之前的第一个编辑中提到的那样,也许它有用吗?不。同样的问题。然后,如果我第二次单击该按钮,表单崩溃,因为等待已被处理?这是一个形式级别的属性,为什么它会被处置?
编辑3 ;好吧,如果我在TextChanged事件中调用wait.Dispose,我会得到所需的行为。除了它最小化主应用程序,只是向我显示MessageBox,除非它背后没有任何东西。儿子......
答案 0 :(得分:0)
对Windows窗体控件进行线程安全调用。要从另一个线程修改winform或控件(BackgroundWorker这样做),您应该从主线程进行此调用。在这个问题中,您有答案:How to update the GUI from another thread in C#?