/* * ///<summary>Must make sure Refresh is done first. Returns the sum of all adjustments for this patient. Amount might be pos or neg.</summary> * public static double ComputeBal(Adjustment[] List){ * double retVal=0; * for(int i=0;i<List.Length;i++){ * retVal+=List[i].AdjAmt; * } * return retVal; * }*/ ///<summary>Returns the number of finance or billing charges deleted.</summary> public static long UndoFinanceOrBillingCharges(DateTime dateUndo, bool isBillingCharges) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetLong(MethodBase.GetCurrentMethod(), dateUndo, isBillingCharges)); } string adjTypeStr = "Finance"; long adjTypeDefNum = PrefC.GetLong(PrefName.FinanceChargeAdjustmentType); if (isBillingCharges) { adjTypeStr = "Billing"; adjTypeDefNum = PrefC.GetLong(PrefName.BillingChargeAdjustmentType); } string command = "SELECT adjustment.AdjAmt,patient.PatNum,patient.Guarantor,patient.LName,patient.FName,patient.Preferred,patient.MiddleI," + "adjustment.SecDateTEdit " + "FROM adjustment " + "INNER JOIN patient ON patient.PatNum=adjustment.PatNum " + "WHERE AdjDate=" + POut.Date(dateUndo) + " " + "AND AdjType=" + POut.Long(adjTypeDefNum); DataTable table = Db.GetTable(command); List <Action> listActions = new List <Action>(); int loopCount = 0; foreach (DataRow row in table.Rows) //loops through the rows and creates audit trail entry for every row to be deleted { listActions.Add(new Action(() => { SecurityLogs.MakeLogEntry(Permissions.AdjustmentEdit, PIn.Long(row["PatNum"].ToString()), "Delete adjustment for patient, undo " + adjTypeStr.ToLower() + " charges: " + Patients.GetNameLF(row["LName"].ToString(), row["FName"].ToString(), row["Preferred"].ToString(), row["MiddleI"].ToString()) + ", " + PIn.Double(row["AdjAmt"].ToString()).ToString("c"), 0, PIn.DateT(row["SecDateTEdit"].ToString())); if (++loopCount % 5 == 0) { BillingEvent.Fire(ODEventType.Billing, Lans.g("FinanceCharge", "Creating log entries for " + adjTypeStr.ToLower() + " charges") + ": " + loopCount + " out of " + table.Rows.Count); } })); } ODThread.RunParallel(listActions, TimeSpan.FromMinutes(2)); command = "DELETE FROM adjustment WHERE AdjDate=" + POut.Date(dateUndo) + " AND AdjType=" + POut.Long(adjTypeDefNum); BillingEvent.Fire(ODEventType.Billing, Lans.g("FinanceCharge", "Deleting") + " " + table.Rows.Count + " " + Lans.g("FinanceCharge", adjTypeStr.ToLower() + " charge adjustments") + "..."); return(Db.NonQ(command)); }
///<summary>The ThreadStatic database context should be inherited by any child thread that is spawned.</summary> public void ODThread_SetDbT_ParentChildDatabaseContext() { Exception ex = null; string methodName = MethodBase.GetCurrentMethod().Name; string databaseName = POut.String(methodName).ToLower(); string odThreadGroupName = methodName + "_GroupName"; //The main thread needs to connect to a unique database that the child thread should NOT end up getting connected to. //Use a query to get our current database context because unit tests utilizes a connection string and we only care about DataConnection.Database string databaseMain = LargeTableHelper.GetCurrentDatabase(); //should be pointing to a 'unittestXXX' database Assert.IsFalse(string.IsNullOrEmpty(databaseMain)); try { ODThread odThreadParent = new ODThread(workerParent => { //The parent thread needs to connect to a database that the main thread is not connected to. CreateDatabaseIfNeeded(databaseName); new DataConnection().SetDbT("localhost", databaseName, "root", "", "", "", DatabaseType.MySql); VerifyCurrentDatabaseName(databaseName); //Now the parent should spawn a child thread which should default to the thread specific database connection from the parent. ODThread odThreadChild = new ODThread(workerChild => { //The child thread should default to the database context of its parent and NOT the database context from the main thread. VerifyCurrentDatabaseName(databaseName); }); odThreadChild.AddExceptionHandler(e => ex = e); odThreadChild.Name = MethodBase.GetCurrentMethod().Name + "_Child"; odThreadChild.GroupName = odThreadGroupName; odThreadChild.Start(); odThreadChild.Join(Timeout.Infinite); VerifyCurrentDatabaseName(databaseName); }); odThreadParent.AddExceptionHandler(e => ex = e); odThreadParent.Name = MethodBase.GetCurrentMethod().Name + "_Parent"; odThreadParent.GroupName = odThreadGroupName; odThreadParent.Start(); odThreadParent.Join(Timeout.Infinite); //Manually join the parent to the main thread so that we know for certain that our child thread exists. VerifyCurrentDatabaseName(databaseMain); } catch (Exception e) { ex = e; } finally { DropDatabase(databaseName); } Assert.IsNull(ex, ex?.Message); //Asserts do not bubble up as expected to the main thread so do a manual assert at the end of the day. }
private void WorkerThread_KeyboardListener(ODThread odThread) { if (!DroppedDown) { return; } try { Invoke(new DelegateKeyboardListener(UpdateInputStates)); } catch (ObjectDisposedException ex) { if (this.IsDisposed) { //On rare occasion, the control is disposed near the same instant that it is Ivoked above. //In this situation, we are quiting the thread, thus we expect the control to be disposed and ignore the error. return; } throw ex; } }
///<summary>Will process payments for all authorized charges for each CC stored and marked for recurring charges. ///X-Charge or PayConnect or PaySimple must be enabled. ///Program validation done on load and if properties are not valid the form will close and exit.</summary> private void butSend_Click(object sender, EventArgs e) { if (_charger.IsCharging) { return; } RefreshRecurringCharges(false, true); if (gridMain.SelectedIndices.Length < 1) { MsgBox.Show(this, "Must select at least one recurring charge."); return; } if (!Security.IsAuthorized(Permissions.PaymentCreate)) { return; } _charger.IsCharging = true; //Doing this on the main thread in case another click event gets here before the thread can start //Not checking DatePay for FutureTransactionDate pref violation because these should always have a date <= today Cursor = Cursors.WaitCursor; List <RecurringChargeData> listCharges = gridMain.SelectedTags <RecurringChargeData>(); bool doForceDuplicates = checkForceDuplicates.Checked; ODThread chargeCreationThread = new ODThread(o => { _charger.SendCharges(listCharges, doForceDuplicates); if (IsDisposed) { return; } try { this.Invoke(() => { FillGrid(true); Cursor = Cursors.Default; MsgBox.Show(this, "Done charging cards.\r\nIf there are any patients remaining in list, print the list and handle each one manually."); }); } catch (ObjectDisposedException) { //This likely occurred if the user clicked Close before the charges were done processing. Since we don't need to display the grid, we can //do nothing. } }); chargeCreationThread.Name = "RecurringChargeProcessor"; chargeCreationThread.Start(); }
///<summary>Returns a list of all versions ordered by MajorNum, MinorNum, BuildNum, and IsForeign.</summary> public static List <VersionRelease> Refresh() { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetObject <List <VersionRelease> >(MethodBase.GetCurrentMethod())); } //Create an ODThread so that we can safely change the database connection settings without affecting the calling method's connection. ODThread odThread = new ODThread(new ODThread.WorkerDelegate((ODThread o) => { //Always set the thread static database connection variables to set the serviceshq db conn. #if DEBUG new DataConnection().SetDbT("localhost", "bugs", "root", "", "", "", DatabaseType.MySql, true); #else new DataConnection().SetDbT("server", "bugs", "root", "", "", "", DatabaseType.MySql, true); #endif string command = "SELECT * FROM versionrelease "; //Exclude black listed versions. for (int i = 0; i < _versionsBlackList.Count; i++) { if (i == 0) { command += "WHERE "; } else { command += "AND "; } command += "(MajorNum,MinorNum) != (" + POut.Int(_versionsBlackList[i].Major) + "," + POut.Int(_versionsBlackList[i].Minor) + ") "; } //The order is very important to other entites calling this method. command += "ORDER BY MajorNum DESC,MinorNum DESC,BuildNum DESC,IsForeign"; o.Tag = RefreshAndFill(command); })); odThread.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => { })); //Do nothing odThread.Name = "versionGetterThread"; odThread.Start(true); if (!odThread.Join(2000)) //Give this thread up to 2 seconds to complete. { return(null); } return((List <VersionRelease>)odThread.Tag); }
private void StartShouldCloseMonitor() { if (_threadShouldWindowClose != null) { return; } _threadShouldWindowClose = new ODThread(500, (o) => { if (_shouldWindowClose) { ODException.SwallowAnyException(() => { Invoke(new Action(() => { DialogResult = DialogResult.OK; })); }); o.QuitAsync(); } }); _threadShouldWindowClose.Name = "FormConnectionLost_ShouldCloseMonitorThread"; _threadShouldWindowClose.AddExceptionHandler((e) => e.DoNothing()); _threadShouldWindowClose.AddExitHandler((e) => _threadShouldWindowClose = null); _threadShouldWindowClose.Start(); }
///<summary>Attempts to open files that will be updated in the destination dir to check if any are currently in use. ///Attempts to create temporary directories that will house the installation files temporarily. ///Attempts to copy all files in the destination directory to a temp directory so that files can be reverted in case of a catastrophic failure. ///Attempts to copy all files in the source directory to a local temp directory. ///Attempts to move all files from the source temp directory into the destination directory.</summary> private void OnThreadStart(ODThread odThread) { SetLabelText("Preparing to Copy Files..."); //Delay the thread for 300 milliseconds to make sure the above processes have really exited. Thread.Sleep(300); //Any file exclusions will have happened when originally copying files into the AtoZ folder. Ex: FreeDentalConfig.xml //And that happens in OpenDental.PrefL.CheckProgramVersion(). DirectoryInfo dirInfoSource = new DirectoryInfo(_sourceDirectory); FileInfo[] arraySourceFiles = dirInfoSource.GetFiles(); DirectoryInfo dirInfoDest = new DirectoryInfo(_destDirectory); FileInfo[] arrayDestFiles = dirInfoDest.GetFiles(); _hasFilesInUse = false; _hasCopyFailed = false; //Recreate the temp directories that will be used in the copying process if (!CreateTempDirectories()) { _hasCopyFailed = true; return; } //Check if any of the corresponding files in the installation directory are in use. if (HasFilesInUse(arraySourceFiles, arrayDestFiles)) { _hasFilesInUse = true; return; } if (!CopyFilesFromDestToTemp(arrayDestFiles) || !CopyFilesFromSourceToTemp(arraySourceFiles)) { _hasCopyFailed = true; return; } if (!MoveFilesToDestDir(arraySourceFiles)) { RevertDestFiles(arrayDestFiles); //Revert the files in the destination directory back to the way they were before trying to update them. _hasCopyFailed = true; return; } CleanUp(); }
///<summary>Gets one EServiceSignalHQ from the serviceshq db located on SERVER184. Returns null in case of failure.</summary> public static EServiceMetrics GetEServiceMetricsFromSignalHQ() { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetObject <EServiceMetrics>(MethodBase.GetCurrentMethod())); } //Create an ODThread so that we can safely change the database connection settings without affecting the calling method's connection. ODThread odThread = new ODThread(new ODThread.WorkerDelegate((ODThread o) => { //Always set the thread static database connection variables to set the serviceshq db conn. new DataConnection().SetDbT("server184", "serviceshq", "root", "", "", "", DatabaseType.MySql, true); //See EServiceSignalHQs.GetEServiceMetrics() for details. string command = @"SELECT 0 EServiceSignalNum, h.* FROM eservicesignalhq h WHERE h.ReasonCode=1024 AND h.ReasonCategory=1 AND h.ServiceCode=2 AND h.RegistrationKeyNum=-1 ORDER BY h.SigDateTime DESC LIMIT 1" ; EServiceSignal eServiceSignal = Crud.EServiceSignalCrud.SelectOne(command); EServiceMetrics eServiceMetric = new EServiceMetrics(); if (eServiceSignal != null) { using (XmlReader reader = XmlReader.Create(new System.IO.StringReader(eServiceSignal.Tag))) { eServiceMetric = (EServiceMetrics) new XmlSerializer(typeof(EServiceMetrics)).Deserialize(reader); } eServiceMetric.IsValid = true; } o.Tag = eServiceMetric; })); odThread.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => { })); //Do nothing odThread.Name = "eServiceMetricsThread"; odThread.Start(true); if (!odThread.Join(2000)) //Give this thread up to 2 seconds to complete. { return(null); } EServiceMetrics retVal = (EServiceMetrics)odThread.Tag; return(retVal); }
private void ConnectAndRunProviderReport(ODThread odThread) { CentralConnection conn = (CentralConnection)odThread.Parameters[0]; DataSet listProdData = null; if (!CentralConnectionHelper.UpdateCentralConnection(conn, false)) { odThread.Tag = new object[] { listProdData, conn }; conn.ConnectionStatus = "OFFLINE"; return; } List <Provider> listProvs = Providers.GetProvsNoCache(); List <Clinic> listClinics = Clinics.GetClinicsNoCache(); Clinic unassigned = new Clinic(); unassigned.ClinicNum = 0; unassigned.Description = "Unassigned"; //Same issue here as above. listClinics.Add(unassigned); listProdData = RpProdInc.GetProviderDataForClinics(_dateFrom, _dateTo, listProvs, listClinics, radioWriteoffPay.Checked, true, true, false, checkShowUnearned.Checked, true); odThread.Tag = new object[] { listProdData, conn, listProvs }; }
private void ConnectAndRunAnnualReport(ODThread odThread) { CentralConnection conn = (CentralConnection)odThread.Parameters[0]; DataSet listProdData = null; if (!CentralConnectionHelper.UpdateCentralConnection(conn, false)) { odThread.Tag = new object[] { listProdData, conn }; conn.ConnectionStatus = "OFFLINE"; return; } List <Provider> listProvs = Providers.GetProvsNoCache(); List <Clinic> listClinics = Clinics.GetClinicsNoCache(); Clinic unassigned = new Clinic(); unassigned.ClinicNum = 0; unassigned.Description = "Unassigned"; //Is this how we should do this? Will there always be different clinics? (I assume so, otherwise CEMT is kinda worthless) listClinics.Add(unassigned); listProdData = RpProdInc.GetAnnualData(_dateFrom, _dateTo, listProvs, listClinics, radioWriteoffPay.Checked, true, true, false, checkShowUnearned.Checked, true); odThread.Tag = new object[] { listProdData, conn }; }
///<summary>Tests that RunParallel itself is a synchronous method call, meaning that any subsequent code will not execute until either the timeout ///is reached or all actions are completed.</summary> public void ODThread_RunParallel_IsSynchronous() { int timeoutMS = 1; DateTime start = DateTime.Now; object testObject = null; bool isRunParallelFinished = false; List <Action> listActions = new List <Action>(); listActions.Add(() => { while (!isRunParallelFinished) { //Wait here until ODThread.RunParallel finishes. } testObject = new object(); //This line should never execute. }); int numThreads = 4; //Mimic what is used in AccountModules.GetAll(...). ODThread.RunParallel(listActions, timeoutMS, numThreads); isRunParallelFinished = true; Assert.IsNull(testObject); //Thread did not finish naturally; was aborted due to timeout. }
private void DropDownToggle() { if (DroppedDown) //DroppedDown, so we need to collapse. { butDrop.ImageIndex = 0; //Set to arrow down image. _popup.Close(); //This collapses the popup. The popup is NOT disposed. FillText(); if (SelectionChangeCommitted != null) { SelectionChangeCommitted(this, new EventArgs()); } } else //Not DroppedDown, so we need to DropDown. { butDrop.ImageIndex = 1; //Set to arrow up image. #region Popup setup _popup = new PopupWindow(gridMain); _popup.AutoClose = false; //This prevents the Alt key from collapsing the combobox and prevents other events from collapsing as well. _popup.Closed += PopupWindow_Closed; _popup.Opened += PopupWindow_Opened; Control parent = Parent; int x = this.Location.X; int y = this.Location.Y; while (parent != null && !typeof(Form).IsAssignableFrom(parent.GetType())) { x += parent.Location.X; y += parent.Location.Y; parent = parent.Parent; } #endregion Popup setup _popup.Show(ParentForm, new Point(x, y + this.Height)); } //The keyboard listener lifetime begins on first dropdown and ends when the control is disposed or parent form is closed. if (_threadCheckKeyboard == null) { //When DroppedDown, will update input flags for auto collapsing. _threadCheckKeyboard = new ODThread(100, WorkerThread_KeyboardListener); _threadCheckKeyboard.Start(); } }
///<summary>Loops through all connections passed in and spawns a thread for each to go fetch patient data from each db using the given filters.</summary> private void StartThreadsForConns() { _dataConnPats.Tables.Clear(); bool hasConnsSkipped = false; for (int i = 0; i < ListConns.Count; i++) { //Filter the threads by their connection name string connName = ""; if (ListConns[i].DatabaseName == "") //uri { connName = ListConns[i].ServiceURI; } else { connName = ListConns[i].ServerName + ", " + ListConns[i].DatabaseName; } if (!connName.Contains(textConn.Text)) { //Do NOT spawn a thread to go fetch data for this connection because the user has filtered it out. //Increment the completed thread count and continue. hasConnsSkipped = true; lock (_lockObj) { _complConnAmt++; } continue; } //At this point we know the connection has not been filtered out, so fire up a thread to go get the patient data table for the search. ODThread odThread = new ODThread(GetPtDataTableForConn, new object[] { ListConns[i] }); odThread.GroupName = "FetchPats"; odThread.Start(); } if (hasConnsSkipped) { //There is a chance that some threads finished (by failing, etc) before the end of the loop where we spawned the threads //so we want to guarantee that the failure message shows if any connection was skipped. //This is required because FillGrid contains code that only shows a warning message when all connections have finished. FillGrid(); } }
///<summary>Returns distinct list of email strings to be recommended to user. ///Splits all email address fields into a large list of individual addresses into one large distinct list. ///When given list is null, will run query.</summary> private void SetHistoricContacts(List<EmailMessage> listEmailMessages) { if(EmailAddressPreview==null) { //Only null when failed to match from address. If we do not know the from address then we can't load anything useful. return; } EmailAddress emailAddressPreview=EmailAddressPreview.Clone(); ODThread thread=new ODThread(o => { List<string> listHistoricContacts; if(listEmailMessages==null) { listHistoricContacts=EmailMessages.GetHistoricalEmailAddresses(emailAddressPreview); } else { listHistoricContacts=EmailMessages.GetAddressesFromMessages(listEmailMessages); } this.InvokeIfRequired(() => { _listHistoricContacts=listHistoricContacts; _hasSetHistoricContacts=true; }); }); thread.Name="SetHistoricContacts"; thread.Start(); }
public void Reports_GetTable_MySqlUserLow() { Exception ex = null; //Spawn a new thread so that we don't manipulate any global DataConnection settings. ODThread thread = new ODThread(o => { //Prepare some simple queries to verify how both user and user low react. string tempTableName = "tmpreportsunittesttable"; string tempTableDropQuery = $"DROP TABLE IF EXISTS {tempTableName}"; string tempTableCreateQuery = $"CREATE TABLE {tempTableName} (Col1 VARCHAR(1))"; string tempTableShowQuery = $"SHOW TABLES LIKE '{tempTableName}'"; //Make sure that we can create and drop tables as the normal user but cannot do the same thing via Reports.GetTable(). //First, make sure that the regular user works as intended. DataCore.NonQ(tempTableDropQuery); DataCore.NonQ(tempTableCreateQuery); Assert.AreEqual(1, DataCore.GetTable(tempTableShowQuery).Rows.Count, "Root user was not able to create a new table."); DataCore.NonQ(tempTableDropQuery); //Next, make sure that user low cannot create the new table. Required to use the Middle Tier otherwise user low is ignored. DataAction.RunMiddleTierMock(() => { //User low should be able to run SELECT and SHOW commands. if (Reports.GetTable(tempTableShowQuery).Rows.Count != 0) //Should have been dropped via root user above. { throw new ApplicationException("Temporary table was not dropped correctly."); } //Reports.GetTable() should throw an exception due to the lack of the CREATE permission. Swallow it. ODException.SwallowAnyException(() => Reports.GetTable(tempTableCreateQuery)); //User low should not have been able to create the table. if (Reports.GetTable(tempTableShowQuery).Rows.Count != 0) { throw new ApplicationException("User low was able to create a table."); } }); }); thread.AddExceptionHandler(e => { ex = e; }); //This will cause the unit test to fail. thread.Name = "thread" + MethodBase.GetCurrentMethod().Name; thread.Start(); thread.Join(Timeout.Infinite); Assert.IsNull(ex, ex?.Message); }
///<summary>Perform the given function in the context of the given connectionName db and return a T.</summary> private static T GetT <T>(Func <T> fn, Action aSetConnection) { Exception eFinal = null; //Reference types will be set to null. T ret = default(T); ODThread th = new ODThread(new ODThread.WorkerDelegate((thread) => { aSetConnection(); ret = fn(); })); th.AddExceptionHandler(new ODThread.ExceptionDelegate((e) => { eFinal = e; })); th.Start(true); //This is intended to be a blocking call so give the action as long as it needs to complete. th.Join(System.Threading.Timeout.Infinite); if (eFinal != null) //We are back on the main thread so it is safe to throw. { throw new Exception(eFinal.Message, eFinal); } return(ret); }
///<summary></summary> private static string RunWebMethod(Func <string> funcWebMethod) { Exception ex = null; //Create an ODThread so that we can safely change the database connection settings without affecting the calling method's connection. ODThread odThread = new ODThread(new ODThread.WorkerDelegate((ODThread o) => { //Change the thread static remoting role to ServerWeb and then execute the func that was passed in. RemotingClient.SetRemotingRoleT(RemotingRole.ServerWeb); o.Tag = funcWebMethod(); })); odThread.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => { ex = e; //Cannot throw exception here due to still being in a threaded context. })); if (ex != null) { throw ex; //Should never happen because this would be a "web exception" as in the ProcessRequest could not even invoke or something like that. } odThread.Name = "threadMiddleTierUnitTestRunWebMethod"; odThread.Start(true); odThread.Join(System.Threading.Timeout.Infinite); return((string)odThread.Tag); }
private void butRefresh_Click(object sender, EventArgs e) { ODThread.JoinThreadsByGroupName(1, "FetchPats"); //Stop fetching immediately _hasWarningShown = false; lock (_lockObj) { _invalidConnsLog = ""; } if (butRefresh.Text == Lans.g(this, "Refresh")) { _dataConnPats.Clear(); butRefresh.Text = Lans.g(this, "Stop Refresh"); labelFetch.Visible = true; _complConnAmt = 0; StartThreadsForConns(); } else { butRefresh.Text = Lans.g(this, "Refresh"); labelFetch.Visible = false; _complConnAmt = ListConns.Count; } }
///<summary>Commits the filter action according to the delayed interval and input wakeup algorithm which uses FilterCommitMs.</summary> private void Control_FilterChange(object sender, EventArgs e) { if (!HasShown) { //Form has not finished the Load(...) function. //Odds are the form is initializing a filter in the form load and the TextChanged, CheckChanged, etc fired prematurely. return; } Control control = (Control)sender; if (!TryGetFilterInfo(control)) { return; } if (IsDisposedOrClosed(this)) { //FormClosed even has already occurred. Can happen if a control in _listFilterControls has a filter action subscribed to an event that occurs after the //FormClosed event, ex CellLeave in FormQueryParser triggers TextBox.TextChanged when closing via shortcut keys (Alt+O). return; } _timeLastModified = DateTime.Now; if (_threadFilter == null) //Ignore if we are already running the thread to perform a refresh. //The thread does not ever run in a form where the user has not modified the filters. { #region Init _threadFilter this.FormClosed += new FormClosedEventHandler(this.ODForm_FormClosed); //Wait until closed event so inheritor has a chance to cancel closing event. //No need to add thread waiting. We will take care of this with FilterCommitMs within our own thread when it runs. _threadFilter = new ODThread(1, ((t) => { ThreadCheckFilterChangeCommited(t); })); _threadFilter.Name = "ODFormFilterThread_" + Name; //Do not add an exception handler here. It would inadvertantly swallow real exceptions as thrown by the Main thread. _threadFilter.Start(false); //We will quit the thread ourselves so we can track other variables. #endregion } else { _threadFilter.Wakeup(); } }
///<summary>Returns a fully formatted string of the possible head version.</summary> public static string GetPossibleHeadRelease() { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetString(MethodBase.GetCurrentMethod())); } //Create an ODThread so that we can safely change the database connection settings without affecting the calling method's connection. ODThread odThread = new ODThread(new ODThread.WorkerDelegate((ODThread o) => { //Always set the thread static database connection variables to set the serviceshq db conn. #if DEBUG new DataConnection().SetDbT("localhost", "bugs", "root", "", "", "", DatabaseType.MySql, true); #else new DataConnection().SetDbT("server", "bugs", "root", "", "", "", DatabaseType.MySql, true); #endif string command = "SELECT * FROM versionrelease " + "WHERE DateRelease < '1880-01-01' " //we are only interested in non-released versions. + "AND IsForeign=0 "; //Exclude black listed versions. for (int i = 0; i < _versionsBlackList.Count; i++) { command += "AND (MajorNum,MinorNum) != (" + POut.Int(_versionsBlackList[i].Major) + "," + POut.Int(_versionsBlackList[i].Minor) + ") "; } command += "ORDER BY MajorNum DESC,MinorNum DESC,BuildNum DESC " + "LIMIT 3"; //Might not be 3. List <VersionRelease> releaseList = RefreshAndFill(command); string versionsString = releaseList[0].MajorNum.ToString() + "." + (releaseList[0].MinorNum + 1).ToString(); o.Tag = versionsString; })); odThread.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => { })); //Do nothing odThread.Name = "versionGetterThread"; odThread.Start(true); if (!odThread.Join(2000)) //Give this thread up to 2 seconds to complete. { return(null); } return(odThread.Tag.ToString()); }
///<summary>Fires a MiddleTierConnectionEvent of type MiddleTierConnectionLost to notify the main thread that the Middle Tier connection has been lost. ///Wait here until the connection is restored.</summary> private static void RemoteConnectionFailed() { RemotingClient.HasMiddleTierConnectionFailed = true; //Inform all threads that we've lost the MiddleTier connection, so they can handle this appropriately. MiddleTierConnectionEvent.Fire(new MiddleTierConnectionEventArgs(false)); //Keep the current thread stuck here while automatically retrying the connection up until the timeout specified. DateTime beginning = DateTime.Now; ODThread threadRetry = new ODThread(500, (o) => { if (!HasMiddleTierConnectionFailed) { o.QuitAsync(); return; } if ((DateTime.Now - beginning).TotalSeconds >= TimeSpan.FromHours(4).TotalSeconds) { return; //We have reached or exceeded the timeout. Stop automatically retrying and leave it up to a manual retry from the user. } try { if (IsMiddleTierAvailable()) { //Unset HasMiddleTierConnectionFailed flag allowing any blocked Middle Tier communication to continue. RemotingClient.HasMiddleTierConnectionFailed = false; //Also fire a DataConnectionEvent letting everyone who cares know that the connection has been restored. MiddleTierConnectionEvent.Fire(new MiddleTierConnectionEventArgs(true)); o.QuitAsync(); } } catch (Exception ex) { ex.DoNothing(); //Connection has not been restored yet. Wait a little bit and then try again. } }); threadRetry.Name = "MiddleTierConnectionLostAutoRetryThread"; threadRetry.AddExceptionHandler((e) => e.DoNothing()); threadRetry.Start(); //Wait here until the retry thread has finished which is either due to connection being restored or the timeout was reached. threadRetry.Join(Timeout.Infinite); //Wait forever because the retry thread has a timeout within itself. }
private void FormJobDashboard_Load(object sender, EventArgs e) { this.WindowState = FormWindowState.Maximized; Color color0 = Color.DarkSlateGray; Color color1 = Color.LightSlateGray; bool useColor0 = true; foreach (Userod user in Userods.GetUsersByJobRole(JobPerm.Engineer, false).OrderByDescending(x => x.UserName)) { JobManagerUserOverview jobManage; if (useColor0) { jobManage = new JobManagerUserOverview(color0); useColor0 = false; } else { jobManage = new JobManagerUserOverview(color1); useColor0 = true; } jobManage.User = user; jobManage.Dock = DockStyle.Top; this.Controls.Add(jobManage); } //Fills all in memory data from the DB on a seperate thread and then refills controls. ODThread thread = new ODThread((o) => { _listJobsAll = Jobs.GetAll(); Jobs.FillInMemoryLists(_listJobsAll); FillDashboard(); }); thread.AddExceptionHandler((ex) => { MessageBox.Show(ex.Message); }); thread.Start(true); _baseFont = Font; _baseSize = Size; }
///<summary>The thread belonging to Control_FilterChange.</summary> private void ThreadCheckFilterChangeCommited(ODThread thread) { //Might be running after FormClosing() foreach (Control control in _listFilterControls) { if (thread.HasQuit) //In case the thread is executing when the user closes the form and QuitSync() is called in FormClosing(). { return; } if (!TryGetFilterInfo(control)) //Just in case. { continue; } double diff = (DateTime.Now - _timeLastModified).TotalMilliseconds; if (diff <= _filterCommitMs) //Time elapsed is less than specified time. { continue; //Check again later. } FilterActionCommit(); thread.Wait(int.MaxValue); //Wait forever... or until Control_FilterChange(...) wakes the thread up or until form is closed. break; //Do not check other controls since we just called the filters action. } }
private void FormShowFeatures_Load(object sender, System.EventArgs e) { checkCapitation.Checked = !PrefC.GetBool(PrefName.EasyHideCapitation); checkMedicaid.Checked = !PrefC.GetBool(PrefName.EasyHideMedicaid); checkPublicHealth.Checked = !PrefC.GetBool(PrefName.EasyHidePublicHealth); checkDentalSchools.Checked = !PrefC.GetBool(PrefName.EasyHideDentalSchools); checkHospitals.Checked = !PrefC.GetBool(PrefName.EasyHideHospitals); checkInsurance.Checked = !PrefC.GetBool(PrefName.EasyHideInsurance); checkClinical.Checked = !PrefC.GetBool(PrefName.EasyHideClinical); checkBasicModules.Checked = PrefC.GetBool(PrefName.EasyBasicModules); _isClinicsEnabledInDb = PrefC.HasClinicsEnabled; RestoreClinicCheckBox(); checkRepeatCharges.Checked = !PrefC.GetBool(PrefName.EasyHideRepeatCharges); checkMedicalIns.Checked = PrefC.GetBool(PrefName.ShowFeatureMedicalInsurance); checkEhr.Checked = PrefC.GetBool(PrefName.ShowFeatureEhr); checkSuperFam.Checked = PrefC.GetBool(PrefName.ShowFeatureSuperfamilies); checkPatClone.Checked = PrefC.GetBool(PrefName.ShowFeaturePatientClone); checkQuestionnaire.Checked = PrefC.GetBool(PrefName.AccountShowQuestionnaire); checkTrojanCollect.Checked = PrefC.GetBool(PrefName.AccountShowTrojanExpressCollect); if (Security.IsAuthorized(Permissions.SecurityAdmin, true)) { //Default error until this thread finishes. _signupException = new Exception(Lan.g(this, "Signup info is still loading")); _threadSignupPortal = new ODThread(new ODThread.WorkerDelegate((th) => { _signupOut = WebServiceMainHQProxy.GetEServiceSetupFull(SignupPortalPermission.FullPermission); //We go this far so allow checkNoClinics_Click(). _signupException = null; })); _threadSignupPortal.AddExceptionHandler(new ODThread.ExceptionDelegate((ex) => { _signupException = ex; })); _threadSignupPortal.AddExitHandler(new ODThread.WorkerDelegate((th) => { _threadSignupPortal = null; })); _threadSignupPortal.Start(); } else { _signupException = new Exception(Lan.g("Security", "Not authorized for") + "\r\n" + GroupPermissions.GetDesc(Permissions.SecurityAdmin)); } }
private void butRefresh_Click(object sender, EventArgs e) { if (textProviderSearch.Text == "" && textClinicSearch.Text == "") { FillGrid(); return; } for (int i = 0; i < gridMain.Rows.Count; i++) { CentralConnection conn = (CentralConnection)gridMain.Rows[i].Tag; if (conn.ConnectionStatus != "OK") { continue; } ODThread odThread = new ODThread(ConnectAndSearch, new object[] { conn }); odThread.Name = "SearchThread" + i; odThread.GroupName = "Search"; odThread.Start(false); } ODThread.JoinThreadsByGroupName(Timeout.Infinite, "Search"); List <ODThread> listComplThreads = ODThread.GetThreadsByGroupName("Search"); List <long> connNums = new List <long>(); for (int i = 0; i < listComplThreads.Count; i++) { object[] obj = (object[])listComplThreads[i].Tag; CentralConnection conn = ((CentralConnection)obj[0]); bool result = ((bool)obj[1]); if (result) { connNums.Add(conn.CentralConnectionNum); } listComplThreads[i].QuitAsync(); } FillGrid(connNums); }
public void FriendlyException_Show_ThrowsInUnitTest() { string strMessageExpected = "Exception thrown."; string strMessageCaught = "FormFriendlyException is not throwing."; //Call FriendlyException in a thread so we don't hang in this test if it fails. ODThread odThread = new ODThread((o) => { try { FriendlyException.Show("FriendlyException", new Exception(strMessageExpected)); } catch (Exception ex) { strMessageCaught = ex.InnerException.Message; } }); odThread.Start(); int millis = 0; while (strMessageExpected != strMessageCaught && millis < 1000) { System.Threading.Thread.Sleep(1); //sleep 1 milliseconds. millis++; } Assert.AreEqual(strMessageExpected, strMessageCaught); }
private void FormJobNew_Load(object sender, EventArgs e) { textSearch.Text = InitialSearchString; listBoxUsers.Items.Add("Any"); _listUsers = Userods.GetDeepCopy(true); _listUsers.ForEach(x => listBoxUsers.Items.Add(x.UserName)); //Statuses listBoxStatus.Items.Add("Any"); _listJobStatuses = Enum.GetValues(typeof(JobPhase)).Cast <JobPhase>().ToList(); _listJobStatuses.ForEach(x => listBoxStatus.Items.Add(x.ToString())); //Categories listBoxCategory.Items.Add("Any"); _listJobCategory = Enum.GetValues(typeof(JobCategory)).Cast <JobCategory>().ToList(); _listJobCategory.ForEach(x => listBoxCategory.Items.Add(x.ToString())); ODThread thread = new ODThread((o) => { //We can reduce these calls to DB by passing in more data from calling class. if available. _listJobsAll = Jobs.GetAll(); Jobs.FillInMemoryLists(_listJobsAll); _listTasksAll = Tasks.GetMany(_listJobsAll.SelectMany(x => x.ListJobLinks).Where(x => x.LinkType == JobLinkType.Task).Select(x => x.FKey).Distinct().ToList()); _listTaskNotesAll = TaskNotes.GetForTasks(_listTasksAll.Select(x => x.TaskNum).ToList()); _listPatientAll = Patients.GetMultPats(_listJobsAll.SelectMany(x => x.ListJobQuotes).Select(x => x.PatNum).Distinct().ToList()).ToList(); _listPatientAll.AddRange(Patients.GetMultPats(_listTasksAll.FindAll(x => x.ObjectType == TaskObjectType.Patient).Select(x => x.KeyNum).ToList())); try { _listFeatureRequestsAll = FeatureRequests.GetAll(); } catch (Exception ex) { ex.DoNothing(); _listFeatureRequestsAll = new List <FeatureRequest>(); } _listBugsAll = Bugs.GetAll(); this.Invoke((Action)ReadyForSearch); }); thread.AddExceptionHandler((ex) => { /*todo*/ }); thread.Start(); }
///<summary>ODThread should be able to catch all exceptions after abort is called on it. If this test fails, an exception is being thrown and ///not being caught from within ODThread.</summary> public void ODThread_CatchThreadAbortException() { bool result = true; ODThread thread = new ODThread(o => { try { Thread.Sleep(TimeSpan.FromMinutes(10)); } catch (Exception ex) { //The thread abort exception will come in here. Because of some code in this exception, a different type of exception is thrown. ex.DoNothing(); throw new Exception("Exception that is not a ThreadAbortException"); } }); thread.AddExceptionHandler(ex => { //If the exception handler is every reached, the exception caused by aborting was not caught correctly. result = false; }); thread.Start(); Thread.Sleep(TimeSpan.FromSeconds(1)); //Give the thread a chance to start. thread.Join(0); //Will cause abort to occur instantly. thread.Join(Timeout.Infinite); //Now actually join and wait for the thread to finish. Assert.IsTrue(result); }
///<summary>Kills the processes OpenDental and WebCamOD and then starts a file copier thread.</summary> private void StartFileCopierThread() { Cursor = Cursors.WaitCursor; //kill all processes named OpenDental. //If the software has been rebranded, the original exe will NOT be correctly closed. KillProcess("OpenDental"); //kill all processes named WebCamOD. //web cam does not always close properly when updater kills OpenDental //web cam relies on shared library, OpenDentBusiness.dll (shared ref with OpenDental). //if this lib can't be updated then the opendental update/install fails KillProcess("WebCamOD"); KillProcess("ProximityOD"); //Kill known applications that are present within the installation directory so that the resources are freed if currently in use. //A customer complained on the forums about CentralManager explicitly. DatabaseIntegrityCheck and ServiceManager are just in case. KillProcess("CentralManager"); KillProcess("DatabaseIntegrityCheck"); KillProcess("ServiceManager"); //Create a separate thread to copy over the files from the UpdateFiles folder share. //In putting this logic in a thread, the user can close the window and not disrupt the copying process. ODThread odThread = new ODThread(OnThreadStart); odThread.AddExitHandler(OnThreadComplete); odThread.Start(true); }
private void WorkerParse834(ODThread odThread) { Load834_Safe(); odThread.QuitAsync(); }