C# 在DialogForm上显示MessageBox会导致奇怪的UI故障

C# 在DialogForm上显示MessageBox会导致奇怪的UI故障,c#,multithreading,winforms,devexpress,C#,Multithreading,Winforms,Devexpress,我的表单上有一个按钮,单击该按钮时,会执行以下操作: private void btnCheckSVN_Click(object sender, EventArgs e) { wait = new DevExpress.Utils.WaitDialogForm("Fetching File SVN Status", "Please Wait"); wait.AutoSize = tru

我的表单上有一个按钮,单击该按钮时,会执行以下操作:

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();
}
按照这样的操作顺序,您(显然)仍然可以看到
消息框后面的Wait对话框,在我看来,它看起来非常草率

如果我切换If语句和
Close()
调用,我的
WaitDialogForm
一半会因为缺少更好的术语而消失。有一个红色边框的空矩形和一个巨大的X穿过它,然后是顶部的
MessageBox
作为它自己的形式

这是我第一次乱搞任何类型的多线程或使用
BackgroundWorker
对象,所以我肯定我错过了一些非常愚蠢的东西,但我不知道是什么

我尝试从此事件中完全删除
消息框
,而是执行以下操作:

 wait.Close();
 lblTotalFileCount.Text = dt.Rows.Count.ToString();
然后处理标签的TextChanged事件并检查是否应显示MessageBox,然后。。。但我还是得到了与红色框相同的结果

编辑;还有,我注意到一件奇怪的事。加载表单时,lblTotalFileCount设置为0。当这个方法运行并说它找到了0个文件时,它会将lblTotalFileCount.Text重新设置为零。。。哪个没有触发TextChanged事件?我知道它被设置为和现在一样的东西,但在技术上仍然有所改变。我是否遗漏了什么,或者事件是否确实检查了该条件并“跳过”了它(如果是这样的话)?我必须将标签设置为空字符串。。。但如果他们运行应用程序,它会设置为0,向他们发出警报,他们会进行一些更改,然后再次运行。。。仍然是0,它不会提醒他们

编辑2;我想,如果我在MessageBox出现之前,尝试在TextChanged事件中调用wait.Close()来编辑我在第一次编辑中提到的标签,也许它会起作用?不。同样的问题。然后,如果我再次单击该按钮,表单就会崩溃,因为等待已被释放?它是表单级属性,为什么要处理它


编辑3;如果我在TextChanged事件中调用wait.Dispose,我会得到所需的行为。除非它最小化了主应用程序,只显示MessageBox,除非它后面什么都没有。a的儿子…

对Windows窗体控件进行线程安全调用。要从另一个线程修改winform或控件(BackgroundWorker会这样做),您应该从主线程进行此调用。在这个问题中,您有您的答案:

Debug+异常,勾选CLR异常的抛出复选框。现在,当绘制事件处理程序引发异常时,调试器将停止。您可能需要基础设施支持的帮助来理解调用堆栈。祝你好运。谢谢你的想法,但它不会抛出异常,与我所提到的启用该功能的代码的任何变体一样。它会。这就是你得到红十字会的原因。只需查看输出窗口,您将看到“first chance exception”调试器通知。首先,确保在UI线程上执行
RunWorkerCompleted
。在您的情况下应该是这样,但在某些情况下不会这样做,特别是当您在实例化它时做了一些非常古怪的事情(不太可能)。如果它不在UI线程上,那么这可能可以解释问题。否则,大红色X通常表示控件有问题。比较
Thread.CurrentThread.ManagedThreadId
btnCheckSVN\u单击
bgwSVn\u RunWorkerCompleted
的输出。它们应该是一样的。另外,如果您将
BackgroundWorker
从工具箱中添加到表单中,那么我几乎可以保证
RunWorkerCompleted
已经在UI线程中。