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; } }