C#thread和ShowDialog问题

时间:2011-05-25 04:42:16

标签: c# winforms multithreading showdialog

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();
        }

    }

MainForm类:

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中,有一个进度条&amp;每500毫秒更新一次进度的计时器。 问题是我仍然可以访问主窗体,我也尝试BeginInvoke但不起作用 谁知道出了什么问题?

由于

已编辑:我发现了这个混乱的来源,它是使用Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile的DeleteFile。用非托管代码替换后,它可以正常工作。

2 个答案:

答案 0 :(得分:1)

尝试

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

答案 1 :(得分:0)

很难确切地说明原因是什么,但你会有更好的机会通过一些调试来发现原因。

我会尝试以下内容;

  • 当您在DeleteForm上运行ShowDialog时,它是否表现为DeleteForm的模式对话框,或者在DeleteForm可见时您仍然可以单击基础表单吗?如果没有,那么当你运行ShowDialog(这个)时呢?

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

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

有关MSDN模态对话的另一个注意事项是使用“关闭”按钮。 以下来自; http://msdn.microsoft.com/en-us/library/w61zzfwe.aspx

  

当表单显示为模态时   在对话框中,单击“关闭”按钮   (带有X的按钮   形式的右上角)导致   要隐藏的形式和   要设置的DialogResult属性   DialogResult.Cancel。与无模式不同   表单,不调用Close方法   当用户使用.NET Framework时   单击a的关闭表单按钮   对话框或设置的值   DialogResult属性。而是   表单被隐藏,可以再次显示   没有创建新的实例   对话框。因为表格显示   因为隐藏了一个对话框而不是   关闭,你必须调用Dispose   形式为否的形式的方法   您的申请需要更长时间。