C#并行For循环完成时不总是退出[间歇错误]

C#并行For循环完成时不总是退出[间歇错误],c#,parallel-processing,progress-bar,parallel-for,C#,Parallel Processing,Progress Bar,Parallel For,因此,我有一个并行for循环,它本身可以完美地工作,基本上它循环通过32000个项集合,并进行一些解析和数学运算,以及其他操作,然后输出预期的结果 创建加载条需要足够长的时间,所以我创建了一个新表单,并在调用此方法之前对其进行了初始化,然后在每个循环完成后向进度条中添加1,这样可以很好地工作,并更新所有内容。然后在循环完成后,加载下一个表单以显示数据,一切正常 现在奇怪的问题是,当我删除更新进度条的单行代码(接近代码末尾)时,这种方法总是能很好地工作,但当我保留它时,它有时会按照我的要求工作,有

因此,我有一个并行for循环,它本身可以完美地工作,基本上它循环通过32000个项集合,并进行一些解析和数学运算,以及其他操作,然后输出预期的结果

创建加载条需要足够长的时间,所以我创建了一个新表单,并在调用此方法之前对其进行了初始化,然后在每个循环完成后向进度条中添加1,这样可以很好地工作,并更新所有内容。然后在循环完成后,加载下一个表单以显示数据,一切正常

现在奇怪的问题是,当我删除更新进度条的单行代码(接近代码末尾)时,这种方法总是能很好地工作,但当我保留它时,它有时会按照我的要求工作,有时它会完成所有处理,并将进度条更新为正常,然后到达末尾并停止,它实际上并没有退出循环并继续执行代码(我可以说,因为它下面的Debug.WriteLine在卡住时不会被触发)。我知道程序没有做任何事情,因为CPU处于空闲状态(当循环工作时,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:Parallel for loop有时只有在我向进度条中添加一行代码以添加1时才会在完成后退出。

如果它在间歇发生,则肯定是竞争条件。不幸的是,它们是最难调试的。使用invoke时,进度报告本身似乎是正确的。也许是别的地方?JiT擅长删除死代码。它首先要清理的一件事是其结果从未实际输出的代码。当您不进行进度报告时,可能会完全跳过错误代码?我建议您使用观察者和可观察的设计模式究竟什么是
Globals
?你不是用一个静态类来保存变量吧?@Enigmativity是的,这只是一个小的学校程序,所以我用了一些狡猾的方法。但到目前为止效果很好。@NesanMano我不确定那是什么,你能提供一个阅读链接吗?