我已经读过关于Invoke(ing)控件和诸如此类的东西......我不知道我应该调用什么控件,因为我的主窗体和对话框形式都有不止一个,因此我的问题在这里。我看过this和this以及this ...我根本不明白如何将它应用到我的情况中。是否有某个教程我会去阅读以试图更好地理解?
我有一个winform应用程序(C#)做了一些工作。其中一些工作可能需要一段时间,所以我想我会提供各种进度对话框,提醒用户正在进行活动(而不是简单地依赖列表控件定期闪烁以指示更新的内容)。
所以,我在项目中添加了一个新表单,添加了一些感兴趣的项目(要处理的项目数,估计完成时间,当前项目和整体进度条)。
public ProgressDialog Progress { get; set; }
public Form1()
{
Progress = new ProgressDialog(this);
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
}
单击“处理”按钮后,我将设置要在后台工作中完成的主要工作。
private void buttonProcess_Click(object sender, EventArgs e)
{
if (backgroundWorker1.IsBusy != true)
{
backgroundWorker1.RunWorkerAsync();
Progress.ShowDialog();
}
}
从在该线程上调用的方法,我在ProgressDialog表单上调用一个方法:
Progress.UpdateDialog(numFiles: filesToProcess.Count,
processTime: TimeSpan.FromTicks(filesToProcess.Count * TimeSpan.TicksPerSecond * 20)); // 20s is an estimated time, it will be updated after first file is processed.
有问题的代码(在ProgressDialog.cs中):
public void UpdateDialog(int percentComplete = 0, string fileName = "", int numFiles = 0, TimeSpan? processTime = null)
{
...
if (numFiles > 0)
{
labelNumFiles.Text = Convert.ToString(numFiles);
}
if (!processTime.Equals(null))
{
labelProcessTime.Text = Convert.ToString(processTime);
}
}
导致以下错误:
An exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll but was not handled in user code
Additional information: Cross-thread operation not valid: Control 'ProgressDialog' accessed from a thread other than the thread it was created on.
此外,主窗体有两个列表控件,需要在处理文件时更新:处理文件列表和错误文件列表。如果我有了添加进度对话框的好主意,那么一切正常。大声笑那么,处理更新进度对话框的正确方法是什么?
答案 0 :(得分:0)
答案 1 :(得分:0)
需要在UI线程上运行UpdateDialog
方法,因为它正在进行UI工作。由于它是在DoWork
的{{1}}期间调用的(很可能没有在您的UI线程上运行),因此您需要对Winforms使用InvokeRequired/Invoke模式:
BackgroundWorker