/// <summary> /// The function called at every timer interval. It checks the backgroundworker isbusy /// state. If not busy then it stops the timer and starts the backgroundworker with the /// saved latest argument. The saved argument is also nulled since that aspect is used /// as a flag. Otherwise the timer is allowed to remain running. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void CheckBackgroundWorkerStateTimer_Elapsed(object sender, ElapsedEventArgs e) { if (bwTableSolutions.IsBusy) { return; } timerRetryUntilNotBusy.Stop(); bwTableSolutions.RunWorkerAsync(m_Argument); m_Argument = null; return; }
private void RunBackgroundWorkerTableSolutions(double cfm, double lph, double surfe, bool colebrook, bool limitvelocity, double vellimit) { TableSolutionArgs thisTableSol = new TableSolutionArgs { Cfm = cfm, Lph = lph, Surfe = surfe, Colebrook = colebrook, Limitvelocity = limitvelocity, Vellimit = vellimit, MaxAr = sessionModel.MaxAR, DLiner = sessionModel.Dliner, LphMargin = sessionModel.LphMargin, Dtype = sessionModel.Dtype, ChkHRange = sessionModel.ChkHRange, HtLL = sessionModel.HtLL, HtUL = sessionModel.HtUL, ChkWRange = sessionModel.ChkWRange, WtLL = sessionModel.WtLL, WtUL = sessionModel.WtUL }; // If not null then there is an argument pending. Throw it out and // replace it with a new argument pending. This serves as both a flag // here and a way to save the most current argument for the waiting // backgroundworker state checker. if (m_Argument != null) { m_Argument = thisTableSol; return; } // Check if backgroundworker is not busy. // Run the not busy backgroundworker with the current argument. if (!bwTableSolutions.IsBusy) { string solTypeText = StrSoluT(); sessionModel.Ductshapevis = Visibility.Hidden; sessionModel.SolutionsMsg = "Calculating " + solTypeText + " Solutions ......."; bwTableSolutions.RunWorkerAsync(thisTableSol); return; } // If here then backgroundworker is currently busy. Save this current desired // argument and then issue a request to cancel the backgroundworker. // Then start the backgroundworker state checker timer. m_Argument = thisTableSol; bwTableSolutions.CancelAsync(); sessionModel.SolutionsMsg = "Calculation cancel is pending ....."; timerRetryUntilNotBusy.Enabled = true; timerRetryUntilNotBusy.Start(); // The request to cancel has been issued and the state checker timer has been // activated. UI returns to user but the revised table has yet to be calculated. // The state checker will start the backgroundworker with the saved argument when // it sees the backgroundworker not busy. return; }
private void BwTableSolutions_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; TableSolutionArgs TSA = e.Argument as TableSolutionArgs; double cfm = TSA.Cfm; double lph = TSA.Lph; double surfe = TSA.Surfe; bool colebrook = TSA.Colebrook; bool limitvelocity = TSA.Limitvelocity; double vellimit = TSA.Vellimit; double maxAr = TSA.MaxAr; double dLiner = TSA.DLiner; double lphMargin = TSA.LphMargin; int dtype = TSA.Dtype; bool chkHRange = TSA.ChkHRange; double htLL = TSA.HtLL; double htUL = TSA.HtUL; bool chkWRange = TSA.ChkWRange; double wtLL = TSA.WtLL; double wtUL = TSA.WtUL; DataTable argSolTable = new SolutionsTable();// TSA.SolutTable; double _tryLPH = 0; double _rEqCirDct = 0; int _maxDuct = 0; int _maxDuctH = 0; int _maxDuctW = 0; double _area_sf = 0; string _typ = null; double _dVel = 0; double _HtBot = 0; double _WtBot = 0; double smallNumber = 5E-3; _maxDuct = Convert.ToInt32(Math.Truncate((maxAr - 1) * ReqEqvCirDuct(cfm, lph, surfe, colebrook, limitvelocity, vellimit))); _maxDuct = Convert.ToInt32(Math.Max(_maxDuct, 6)); // limit lower size _maxDuctH = _maxDuct; _maxDuctW = _maxDuct; _HtBot = 6; _WtBot = 6; if (chkHRange) { _HtBot = htLL; _maxDuctH = Convert.ToInt32(htUL); } if (chkWRange) { _WtBot = wtLL; _maxDuctW = Convert.ToInt32(wtUL); } _typ = (dtype == 0 ? " R" : " FO"); double DDLiner = 2 * dLiner; for (double ductHeight = _HtBot; ductHeight <= _maxDuctH; ductHeight += Dinc) { if ((worker.CancellationPending)) { e.Cancel = true; return; } if (argSolTable.Rows.Count > 60) { break; } // Not adjusting the inner loop lower bound to eliminate mirror duplicates!! The // problem with that approach is that the lower and upper dimension limits can // vary. for (double wt = _WtBot; wt <= _maxDuctW; wt += Dinc) { if ((worker.CancellationPending)) { e.Cancel = true; return; } // check ar and even size first if ((Math.Max(wt, ductHeight) / Math.Min(wt, ductHeight) <= maxAr) && ((wt + DDLiner) % 2 == 0) && ((ductHeight + DDLiner) % 2 == 0)) { _rEqCirDct = DhEqCircRO(ductHeight, wt, dtype); _tryLPH = CircDuctPLPH(cfm, _rEqCirDct, surfe, colebrook); // The viable solution must first come under the lph criterium. Then // it must be close enough to the lph according to the allowed margin factor. if ((_tryLPH <= lph) && ((lphMargin * lph) - _tryLPH <= smallNumber)) { _area_sf = DAreaRO(wt, ductHeight, dtype); _dVel = Vel(cfm, _area_sf); // velocity limit check, if fails then skip this for if ((limitvelocity) && (_dVel > vellimit)) { continue; } double drWt = wt + DDLiner; double drHt = ductHeight + DDLiner; double drPFT = DuctPFT(drWt, drHt, dtype); DataRow dr = argSolTable.NewRow(); // inlist check, if already in list as reverse size then skip this solution if (InList(drHt, drWt, argSolTable)) { continue; } dr[0] = drWt; dr[1] = "x"; dr[2] = drHt; dr[3] = _typ; dr[4] = Math.Round(_tryLPH, 3, MidpointRounding.AwayFromZero).ToString(); dr[5] = _dVel.ToString("#,##0"); dr[6] = Math.Round((Math.Max(wt, ductHeight) / Math.Min(wt, ductHeight)), 2, MidpointRounding.AwayFromZero).ToString("0.00"); dr[7] = drPFT.ToString("0.00"); argSolTable.Rows.Add(dr); } } if (argSolTable.Rows.Count > 60) { break; } } } // sort by aspect ratio first, then by pressure loss // This puts the most efficient section at the list top. // sessionModel.SolTable.DefaultView.Sort = "PFT ASC, AR ASC, PLPH DESC"; argSolTable.DefaultView.Sort = "AR ASC, PLPH ASC"; // Backgroundworker return value e.Result = argSolTable; }