所以我有一个并行的 for 循环,它本身就可以完美地工作,基本上它循环通过一个 32000 个项目集合并进行一些解析和数学运算,然后输出预期的结果。
加载条需要足够长的时间,所以我创建了一个新表单并在调用此方法之前对其进行了初始化,然后在每个循环完成后简单地将 1 添加到进度条,这工作正常,它会更新等等。然后在循环完成后,它意味着加载下一个表单以显示数据,一切都很好。
现在奇怪的问题是,当我删除用于更新进度条的单行(接近代码末尾)时,此方法将始终完美运行,但是当我将其保留时,它有时会按我的意愿工作,有时它将完成所有处理并照常更新进度条,然后到达结束并停止,它实际上并没有退出循环并继续执行代码(我可以知道,因为它下面的 Debug.WriteLine 是卡住时不会触发)。而且我知道程序没有做任何事情,因为 CPU 处于空闲状态(当循环工作时它处于 100% 状态),我无法弄清楚出了什么问题。
这是我的代码:
public void ProcessData()
{
try
{
Globals.frmref.pgbProgress.Value = 0;
string TimeZone = cmbTimeZone.Text;
Globals.frmref.pgbProgress.Maximum = Globals.FileLength - 8;
Parallel.For(0, Globals.FileLength - 9, i =>
{
Globals.data[i].TimeTemp = "{0}/{1}/20{2} {3}:{4}:{5}";
//Process the time and date (received in utc as ddmmyy and HHmmss.fff) to dd/mm/yy HH:mm:ss.fff
Globals.data[i].TimeTemp = String.Format(Globals.data[i].TimeTemp, Globals.data[i].DateRAW.Substring(0, 2), Globals.data[i].DateRAW.Substring(2, 2), Globals.data[i].DateRAW.Substring(4, 2), Globals.data[i].Hours, Globals.data[i].Minutes, Globals.data[i].Seconds);
Globals.data[i].Time = DateTime.Parse(Globals.data[i].TimeTemp.Split('.')[0], CultureInfo.CreateSpecificCulture("en-AU"));
Globals.data[i].Time = Globals.data[i].Time.AddMilliseconds(Double.Parse(Globals.data[i].TimeTemp.Split('.')[1]));
if (TimeZone.Contains("-"))
{
Globals.data[i].Time = Globals.data[i].Time - TimeSpan.Parse(TimeZone.Substring(1, TimeZone.Length - 1));
}
else
{
Globals.data[i].Time = Globals.data[i].Time + TimeSpan.Parse(TimeZone.Substring(1, TimeZone.Length - 1));
}
//Process the lat and lon input to Decimal Degrees
Globals.data[i].DDLat = Globals.data[i].LatDegrees + (Globals.data[i].LatMinutes / 60) + (Globals.data[i].LatSeconds / 3600);
Globals.data[i].DDLon = Globals.data[i].LonDegrees + (Globals.data[i].LonMinutes / 60) + (Globals.data[i].LonSeconds / 3600);
if (Globals.data[i].NS == 'S') //North/South designator
{
//Make the dd coord negative if its southern
Globals.data[i].DDLat = Globals.data[i].DDLat * -1;
}
if (Globals.data[i].EW == 'W') //East/West Designator
{
//ditto
Globals.data[i].DDLon = Globals.data[i].DDLon * -1;
}
//***This is the line breaks it sometimes***
Globals.frmref.pgbProgress.Invoke(new Action(() => Globals.frmref.pgbProgress.Value++));
});
Debug.WriteLine("Made it");
Globals.frmref.Close();
}
catch (Exception ex)
{
MessageBox.Show("An unexpected error has occurred, email wmatt1672@gmail.com with details of the error.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.Exit();
}
}
我尝试在更新之前锁定 ProgressBar 控件,使用 int 存储值,然后通过另一种方法更新进度条,并使用 Task.Factory (它奇怪地运行代码)。我完全没主意了。
tldr:并行 for 循环有时在完成后不会退出,仅当我添加一行代码以将 1 添加到进度条时。