首页 > 解决方案 > C# Parallel For 循环在完成后并不总是退出 [间歇性错误]

问题描述

所以我有一个并行的 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 添加到进度条时。

标签: c#parallel-processingprogress-barparallel-for

解决方案


推荐阅读