C#线程和ShowDialog问题

本文关键字:问题 ShowDialog 线程 | 更新日期: 2023-09-27 17:57:40

ProgressForm类:

public partial class ProgressForm : Form
    {
        public int prc = 0, sz;
        MainForm mf;
        public ProgressForm(MainForm MF)
        {
            InitializeComponent();
            mf = MF;
            sz = 0;
        }
        public ProgressForm(int mx)
        {
            InitializeComponent();
            sz = mx;
        }
        public void SetMax(int mx)
        {
            sz = mx;
        }
        public void StartProgress()
        {
            timer1.Enabled = true;
        }
        public void IncProgress(int prg)
        {
            prc += prg;
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            double pos = (double)prc / (double)sz * 100;
            progressBar.Value = (int)pos;
        }
        private void ProgressForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            timer1.Enabled = false;
        }
        private void cancelBtn_Click(object sender, EventArgs e)
        {
            mf.isCanceled = true;
            this.Close();
        }
        private void ProgressForm_Shown(object sender, EventArgs e)
        {
            progressBar.Value = 0;
            StartProgress();
        }
    }

主窗体类别:

void DeleteFiles()
            {
                int x = 0;
                int cnt = resultList.Count;
                isCanceled = false;
                DeleteThreadHandler("beginprogress");
                try
                {
                    DeleteThreadHandler("begindelete");
                    for (int j = 0; j < cnt; j++)
                    {
                        if (resultList[x].isChecked)
                        {
                            DeleteThreadHandler("progress");
                            DeleteFile(resultList[x].name, deleteForm.isDeletePermanently);
                            if (File.Exists(resultList[x].name))
                            {
                                DeleteErrorHandler(resultList[x].name);
                                isError = true;
                            }
                            else
                                resultList.RemoveAt(x);
                        }
                        else
                            ++x;
                        if (isCanceled)
                            break;
                    }
                }
                finally
                {
                    validity(true);
                    DeleteThreadHandler("enddelete");
                }
            }
            void DeleteErrorHandler(string val)
            {
                Action action = null;
                action = () =>
                {
                    errorReportForm.AddError(val);
                };
                this.BeginInvoke(action);
            }
            void DeleteThreadHandler(String title)
            {
                Action action = null;
                if (title == "beginprogress")
                {
                    action = () =>
                    {
                    };
                }
                else
                if (title == "begindelete")
                {
                    action = () =>
                    {
                        olvVirtual.BeginUpdate();
                    };
                }
                else
                    if (title == "enddelete")
                    {
                        action = () =>
                        {
                            olvVirtual.VirtualListSize = resultList.Count;
                            olvVirtual.EndUpdate();
                            RefreshStatus();
                            progressForm.Close();
                            if (isError)
                                errorReportForm.ShowDialog();
                        };
                    }
                if (title == "progress")
                {
                    action = () =>
                    {
                        progressForm.IncProgress(1);
                    };
                }
                this.BeginInvoke(action);
            }    

    private void DeleteBtn_Click(object sender, EventArgs e)
        {
            int checkedcount = GetCheckedCount();
            if (checkedcount == 0)
            {
                MessageBox.Show("Please mark at least a file first");
                return;
            }
            DialogResult dr = new DialogResult();
            if (deleteForm == null)
                deleteForm = new DeleteForm();
            dr = deleteForm.ShowDialog();
            if (dr == DialogResult.OK)
            {
                //if (progressForm == null)
                progressForm = new ProgressForm(this);
                progressForm.Text = "Deleting...";
                progressForm.SetMax(checkedcount);
                if (errorReportForm == null)
                    errorReportForm = new ErrorReportForm();
                errorReportForm.ClearMemo();
                isError = false;
                Thread t = new Thread(DeleteFiles);
                t.Start();
                progressForm.ShowDialog();
            }
        }

在progressForm中,有一个进度条&定时器,每500ms更新一次进度。问题是我仍然可以访问主窗体,我也尝试了BeginInvoke,但两者都不起作用有人知道怎么了吗?

感谢

编辑:我找到了这个烂摊子的来源,它是使用Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile的DeleteFile。用非托管代码替换它后,它工作得很好。

C#线程和ShowDialog问题

尝试

 progressForm.ShowDialog(this);  // assuming this is the main form

很难说这到底是什么原因,但通过一些调试,您将有更好的机会发现原因。

我会尝试以下内容;

  • 当您在DeleteForm上运行ShowDialog时,这是作为DeleteForm的模式对话框,还是在DeleteForm可见时仍可以单击基础窗体?如果没有,当你运行ShowDialog(这个)时是这样吗?

  • 调用progressForm.ShowDialog(this)并设置几个断点(1)在DeleteFiles的开头,(2)在progressFForm.IncProgress(1)行;当断点被击中时,使用即时窗口检查progressForm.Owner和progressFForm.Modal

此外,您将对当前对象的引用传递到进度表单中是为了什么?ProgressForm的构造函数中是否存在可能导致这些问题的内容?

MSDN中的"模式对话框"中需要注意的另一件事是"关闭"按钮的使用。以下内容来自;http://msdn.microsoft.com/en-us/library/w61zzfwe.aspx

当窗体显示为模态时对话框,单击"关闭"按钮(位于表单的右上角)导致要隐藏的表单和要设置为的DialogResult属性DialogResult.Cancel。与无模式不同窗体,则不调用Close方法当用户单击的关闭窗体按钮对话框,或设置DialogResult属性。相反表单被隐藏,可以再次显示而不创建的新实例对话框。因为显示了一个表单因为对话框是隐藏的,而不是关闭,则必须调用Dispose表单为no时的表单方法您的应用程序需要更长的时间。