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。用非托管代码替换它后,它工作得很好。
尝试
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时的表单方法您的应用程序需要更长的时间。