private bool TrackProgress(ImprovedBackgroundWorker MainThread, ImprovedBackgroundWorker[] RadialThreads, int MinimumBusyWorkerCountBeforeReturn)
        {
            int RunningWorkerCount = RadialThreads.Length;
            float TotalProgress, RadialProgress;
            bool CancellationPending = false;
            float RadialProgressDivisor = 1f / (float)RadialThreads.Length;

            if (MinimumBusyWorkerCountBeforeReturn > RadialThreads.Length)
                throw new ArgumentException("Radial: TrackProgress: Infinite loop requested.  Check your parameters!");

            while (RunningWorkerCount >= MinimumBusyWorkerCountBeforeReturn)
            {
                TotalProgress = 0;
                RunningWorkerCount = 0;
                for (int CurWorker = 0; CurWorker < RadialThreads.Length; CurWorker++)
                {
                    RadialProgress = 0f;
                    if (MainThread.CancellationPending)
                    {
                        CancellationPending = true;
                        if (RadialThreads[CurWorker].IsBusy) RadialThreads[CurWorker].CancelAsync();
                    }
                    if (RadialThreads[CurWorker].IsBusy)
                    {
                        RunningWorkerCount++;
                        RadialProgress = RadialThreads[CurWorker].ProgressPercent * RadialProgressDivisor;
                    }
                    else
                    {
                        if (RadialThreads[CurWorker].HasCompleted)
                        {
                            RadialProgress = 100 * RadialProgressDivisor;
                        }
                        else
                            RadialProgress = 0;
                    }
                    TotalProgress += RadialProgress;
                    mProgress_percent = TotalProgress;
                }
                //System.Diagnostics.Debug.WriteLine(RunningWorkerCount + " worker threads still running");
                MainThread.ReportProgress((int)TotalProgress);
                if (RunningWorkerCount >= MinimumBusyWorkerCountBeforeReturn)
                    Thread.Sleep(500);
            }
            return CancellationPending;
        }
        public void Compute(object sender, DoWorkEventArgs e)
        {
            int CurRadial;
            bool CancellationPending = false;
            ImprovedBackgroundWorker MainWorker = (ImprovedBackgroundWorker)sender;
            ImprovedBackgroundWorker[] RadialWorkers = new ImprovedBackgroundWorker[Radials.Count];
            MainWorker.WorkerReportsProgress = true;
            MainWorker.WorkerSupportsCancellation = true;

            IsComputing = true;
            BinaryFileName = Path.GetFileNameWithoutExtension(Path.GetRandomFileName()) + ".tlf";

            for (CurRadial = 0; CurRadial < Radials.Count; CurRadial++)
                RadialWorkers[CurRadial] = new ImprovedBackgroundWorker("radial " + CurRadial, 
                    new DoWorkEventHandler(Radials[CurRadial].Compute),
                    new DoWorkEventHandler(Radials[CurRadial].Complete), 
                    null);
            for (CurRadial = 0; CurRadial < Radials.Count; CurRadial++)
            {
                // This loop will launch all the threads needed to compute the radials for this TL Field.
                // The maximum number of threads that will run at one time is limited by the number of processors on
                // the host system.
                CancellationPending = TrackProgress(MainWorker, RadialWorkers, System.Environment.ProcessorCount);

                if (CancellationPending)
                    break;

                RadialWorkers[CurRadial].Priority = ThreadPriority.BelowNormal;
                RadialWorkers[CurRadial].RunWorkerAsync(null);
                Thread.Sleep(1000);
            }
            
            if (!CancellationPending)
                CancellationPending = TrackProgress(MainWorker, RadialWorkers, 1);

            if ((CancellationPending) && (FieldData != null) && (File.Exists(FieldData.Filename)))
            {
                File.Delete(FieldData.Filename);
                FieldData = null;
            }
        }