private void StartRefreshThread(Func <UserControlDashboardWidget, bool> funcData, string name) { ODThread previousThread = null; if (_threadRefresh != null && !_threadRefresh.HasQuit) { previousThread = _threadRefresh; } _threadRefresh = new ODThread((o) => { if (previousThread != null) { //Allow the previous thread to finish updating its data, but quit before updating UI if it hasn't started yet. previousThread.QuitSync(Timeout.Infinite); } foreach (UserControlDashboardWidget widget in ListOpenWidgets) { if (funcData(widget)) { if (widget.IsDisposed || !widget.IsHandleCreated) { continue; } if (!o.HasQuit) { widget.RefreshView(); //Invokes back to UI thread for UI update. } } } }); _threadRefresh.Name = name; _threadRefresh.AddExceptionHandler(ex => ex.DoNothing()); //Don't crash program on Dashboard data fetching failure. _threadRefresh.Start(); }
///<Summary>Checks bugIDs in list for incompletes. Returns false if incomplete exists.</Summary> public static bool CheckForCompletion(List <long> listBugIDs) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetBool(MethodBase.GetCurrentMethod(), listBugIDs)); } //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 COUNT(*) FROM bug " + "WHERE VersionsFixed='' " + "AND BugId IN (" + String.Join(",", listBugIDs) + ")"; o.Tag = Db.GetCount(command); })); odThread.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => { })); //Do nothing odThread.Name = "bugsCheckForCompletionThread"; odThread.Start(true); if (!odThread.Join(THREAD_TIMEOUT)) { return(true); } if (PIn.Int(odThread.Tag.ToString()) != 0) { return(false); } return(true); }
///<summary>Wrapper method to call the passed-in func in a seperate thread connected to the reporting server. ///This method should only be used for SELECT, with the exception DashboardAR. Using this for create/update/delete may cause duplicates. ///The return type of this function is whatever the return type of the method you passed in is. ///Throws an exception if anything went wrong executing func within the thread.</summary> ///<param name="doRunOnReportServer">If this false, the func will run against the currently connected server.</param> public static T RunFuncOnReportServer <T>(Func <T> func, bool doRunOnReportServer = true) { if (!doRunOnReportServer) { return(func()); } Exception ex = null; ODThread threadGetTable = new ODThread(new ODThread.WorkerDelegate((ODThread o) => { DataAction.Run(() => { o.Tag = func(); } //set the tag to the func's output. , ConnectionNames.DentalOfficeReportServer); //run on the report server. if not set up, automatically runs on the current server. })); threadGetTable.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => { ex = e; })); threadGetTable.Name = "ReportComplexGetTableThread"; threadGetTable.Start(true); threadGetTable.Join(Timeout.Infinite); //Now that we are back on the main thread, it is now safe to throw exceptions. if (ex != null) { ExceptionDispatchInfo.Capture(ex.InnerException ?? ex).Throw(); //This preserves the stack trace of the InnerException. } return((T)threadGetTable.Tag); }
///<Summary>Gets name from database. Not very efficient.</Summary> public static string GetSubmitterName(long submitter) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetString(MethodBase.GetCurrentMethod(), submitter)); } //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 UserName FROM buguser WHERE BugUserId=" + submitter; o.Tag = Db.GetScalar(command); })); odThread.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => { })); //Do nothing odThread.Name = "bugsGetSubmitterNameThread"; odThread.Start(true); if (!odThread.Join(THREAD_TIMEOUT)) { return(""); } return(odThread.Tag.ToString()); }
///<summary>Can return null if the thread fails to join.</summary> public static List <Bug> GetAll() { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetObject <List <Bug> >(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 bug ORDER BY CreationDate DESC"; o.Tag = Crud.BugCrud.TableToList(DataCore.GetTable(command)); })); odThread.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => { })); //Do nothing odThread.Name = "bugsGetAllThread"; odThread.Start(true); if (!odThread.Join(THREAD_TIMEOUT)) { return(null); } return((List <Bug>)odThread.Tag); }
///<summary></summary> private string RunWebMethod(Func <string> funcWebMethod) { Exception ex = null; RemotingRole remotingRoleCur = RemotingClient.RemotingRole; //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 remoting role to ServerWeb (this will get set back to remotingRoleCur later. RemotingClient.RemotingRole = RemotingRole.ServerWeb; //Set new database connection settings if designated. E.g. some unit tests need to set and utilize userLow and passLow. if (!string.IsNullOrEmpty(_server) && !string.IsNullOrEmpty(_db) && !string.IsNullOrEmpty(_user)) { new DataConnection().SetDbT(_server, _db, _user, _password, _userLow, _passLow, DatabaseType.MySql); } //Execute the func that was passed in now that our remoting role and database connection are correct. 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"; //Set the remoting role back after exiting the thread. odThread.AddExitHandler((e) => RemotingClient.RemotingRole = remotingRoleCur); odThread.Start(true); odThread.Join(System.Threading.Timeout.Infinite); return((string)odThread.Tag); }
///<Summary></Summary> public static void CompleteRequests(List <long> listRequestIDs, string versionText) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { Meth.GetVoid(MethodBase.GetCurrentMethod(), listRequestIDs, versionText); } //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 versionString = "\r\n\r\nCompleted in version " + versionText; string command = "UPDATE request SET Approval=9, " //Complete + "Detail=CONCAT( Detail , '" + versionString + "' ) " + "WHERE RequestId IN (" + String.Join(",", listRequestIDs) + ")"; o.Tag = Db.NonQ(command); })); odThread.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => { })); //Do nothing odThread.Name = "featureCheckForCompletionThread"; odThread.Start(true); if (!odThread.Join(2000)) //Give this thread up to 2 seconds to complete. { return; } }
///<Summary>Will not mark completed feature requests as approved.</Summary> public static void MarkAsApproved(List <long> listRequestIDs) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { Meth.GetVoid(MethodBase.GetCurrentMethod(), listRequestIDs); return; } //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 = "UPDATE request SET Approval=7 " //Approved + "WHERE Approval!=9 " //9=Complete + "AND RequestId IN (" + String.Join(",", listRequestIDs) + ")"; o.Tag = Db.NonQ(command); })); odThread.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => { })); //Do nothing odThread.Name = "featureMarkAsInProgressThread"; odThread.Start(true); if (!odThread.Join(2000)) //Give this thread up to 2 seconds to complete. { return; } }
private void butRefreshConns_Click(object sender, EventArgs e) { Cursor = Cursors.WaitCursor; if (gridMain.SelectedIndices.Length == 0) { gridMain.SetSelected(true); } for (int i = 0; i < gridMain.SelectedIndices.Length; i++) { CentralConnection conn = (CentralConnection)gridMain.Rows[gridMain.SelectedIndices[i]].Tag; if (conn.DatabaseName == "" && conn.ServerName == "" && conn.ServiceURI == "") { continue; } ODThread odThread = new ODThread(ConnectAndVerify, new object[] { conn, _progVersion }); odThread.Name = "VerifyThread" + i; odThread.GroupName = "Verify"; odThread.Start(false); } ODThread.JoinThreadsByGroupName(Timeout.Infinite, "Verify"); List <ODThread> listComplThreads = ODThread.GetThreadsByGroupName("Verify"); for (int i = 0; i < listComplThreads.Count; i++) { object[] obj = (object[])listComplThreads[i].Tag; CentralConnection conn = ((CentralConnection)obj[0]); string status = ((string)obj[1]); CentralConnection connection = _listConns.Find(x => x.CentralConnectionNum == conn.CentralConnectionNum); connection.ConnectionStatus = status; } ODThread.QuitSyncThreadsByGroupName(100, "Verify"); Cursor = Cursors.Default; FillGrid(); }
///<summary>NOT Oracle compatible. This will take a set of rows from the specified table from the current database and insert them into a ///different database. It does NOT create tables nor databases if they don't exist, such things need to already exist. Enter text for the ///"whereClause" parameter to filter what rows to retrieve. Needs to include the "WHERE" statement, if it's being used. (Ex. "WHERE PatNum != 2") ///IMPORTANT NOTE -------------- MAKE SURE YOU SET CLASS-WIDE VARIABLES PRIOR TO RUNNING TABLE COMMANDS. - TableName, TablePriKey at the very least.</summary> public static void InsertIntoLargeTable(string whereClause) { #if DEBUG Stopwatch s = new Stopwatch(); s.Start(); #endif SetListPriKeyMaxPerBatch(whereClause); _tempTableName = _tableName; //Set these to be equal for the Insert function - We aren't renaming tables, we are copying from one to another. ODThread odThreadQueueData = new ODThread(QueueBatches); try { lock (_lockObjQueueBatchQueries) { _queueBatchQueries = new Queue <BatchQueries>(); } _areQueueBatchThreadsDone = false; odThreadQueueData.Name = "QueueDataThread"; odThreadQueueData.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception ex) => { _areQueueBatchThreadsDone = true; })); odThreadQueueData.Start(true); InsertBatches(); } catch (Exception ex) { ex.DoNothing(); throw; } finally { odThreadQueueData?.QuitAsync(); _areQueueBatchThreadsDone = true; #if DEBUG s.Stop(); Console.WriteLine("Total time to insert into table " + _tableName + " with " + string.Format("{0:#,##0.##}", _totalRowCount) + " rows: " + (s.Elapsed.Hours > 0?(s.Elapsed.Hours + " hours "):"") + (s.Elapsed.Minutes > 0?(s.Elapsed.Minutes + " min "):"") + (s.Elapsed.TotalSeconds - (s.Elapsed.Hours * 60 * 60) - (s.Elapsed.Minutes * 60)) + " sec"); #endif } }
void FillGridInsPlans() { _sortedByColumnIdx = gridInsPlans.SortedByColumnIdx; _isSortAscending = gridInsPlans.SortedIsAscending; gridInsPlans.BeginUpdate(); if (gridInsPlans.ListGridColumns.Count == 0) { gridInsPlans.ListGridColumns.Clear(); gridInsPlans.ListGridColumns.Add(new UI.GridColumn("Name", 200, HorizontalAlignment.Left, UI.GridSortingStrategy.StringCompare)); gridInsPlans.ListGridColumns.Add(new UI.GridColumn("Birthdate", 74, HorizontalAlignment.Center, UI.GridSortingStrategy.DateParse)); gridInsPlans.ListGridColumns.Add(new UI.GridColumn("SSN", 66, HorizontalAlignment.Center, UI.GridSortingStrategy.StringCompare)); _patNumCol = gridInsPlans.ListGridColumns.Count; gridInsPlans.ListGridColumns.Add(new UI.GridColumn("PatNum", 68, HorizontalAlignment.Center, UI.GridSortingStrategy.StringCompare)); gridInsPlans.ListGridColumns.Add(new UI.GridColumn("Date Begin", 84, HorizontalAlignment.Center, UI.GridSortingStrategy.DateParse)); gridInsPlans.ListGridColumns.Add(new UI.GridColumn("Date Term", 84, HorizontalAlignment.Center, UI.GridSortingStrategy.DateParse)); gridInsPlans.ListGridColumns.Add(new UI.GridColumn("Relation", 70, HorizontalAlignment.Center, UI.GridSortingStrategy.StringCompare)); gridInsPlans.ListGridColumns.Add(new UI.GridColumn("SubscriberID", 96, HorizontalAlignment.Left, UI.GridSortingStrategy.StringCompare)); gridInsPlans.ListGridColumns.Add(new UI.GridColumn("GroupNum", 100, HorizontalAlignment.Left, UI.GridSortingStrategy.StringCompare)); gridInsPlans.ListGridColumns.Add(new UI.GridColumn("Payer", 0, HorizontalAlignment.Left, UI.GridSortingStrategy.StringCompare)); _sortedByColumnIdx = 0; //Sort by Patient Last Name by default. _isSortAscending = true; //Start with A and progress to Z. } gridInsPlans.EndUpdate(); Application.DoEvents(); //To show empty grid while the window is loading. if (_odThread != null) { _odThread.QuitSync(0); } _odThread = new ODThread(WorkerPreview834); _odThread.Start(); }
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. if (_listJobsAll == null) { _listJobsAll = Jobs.GetAll(); Jobs.FillInMemoryLists(_listJobsAll); } 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>Kills the processes OpenDental and WebCamOD and then starts a file copier thread.</summary> private void StartFileCopierThread() { Cursor = Cursors.WaitCursor; if (_doKillServices) //Generally kill except when dealing with DynamicMode //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); }
///<summary></summary> public static void Open(Claim claim, Action actionOkClick = null) { //Show a dialog if the user tries to open more than one claim at a time if (_threadFormClaimAttach != null) { MsgBox.Show("A claim attachment window is already open."); return; } _threadFormClaimAttach = new ODThread(new ODThread.WorkerDelegate((ODThread o) => { FormClaimAttachment formCA = new FormClaimAttachment(claim); if (formCA.ShowDialog() == DialogResult.OK) { actionOkClick?.Invoke(); } })); //This thread needs to be STA because FormClaimAttachment will have the ability to open child forms, //which will need to block FormClaimAttachment while it is open. //STA mode is the only way to have ShowDialog() behavior in a non-main thread, //without throwing an exception (the exception literally says change the thread to STA) _threadFormClaimAttach.SetApartmentState(System.Threading.ApartmentState.STA); _threadFormClaimAttach.AddExitHandler(new ODThread.WorkerDelegate((ODThread o) => { _threadFormClaimAttach = null; })); _threadFormClaimAttach.Start(true); }
///<summary>Gets one Bug from the db. Can return null if the thread fails to join.</summary> public static Bug GetOne(long bugId) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetObject <Bug>(MethodBase.GetCurrentMethod(), bugId)); } //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 o.Tag = Crud.BugCrud.SelectOne(bugId); })); odThread.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => { })); //Do nothing odThread.Name = "bugsGetOneThread"; odThread.Start(true); if (!odThread.Join(THREAD_TIMEOUT)) { return(null); } return((Bug)odThread.Tag); }
///<summary>Must pass in version as "Maj" or "Maj.Min" or "Maj.Min.Rev". Uses like operator. Can return null if the thread fails to join.</summary> public static List <Bug> GetByVersion(string versionMajMin, string filter = "") { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetObject <List <Bug> >(MethodBase.GetCurrentMethod(), versionMajMin, filter)); } //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 bug WHERE (VersionsFound LIKE '" + POut.String(versionMajMin) + "%' OR VersionsFound LIKE '%;" + POut.String(versionMajMin) + "%' OR " + "VersionsFixed LIKE '" + POut.String(versionMajMin) + "%' OR VersionsFixed LIKE '%;" + POut.String(versionMajMin) + "%') "; if (filter != "") { command += "AND Description LIKE '%" + POut.String(filter) + "%'"; } o.Tag = Crud.BugCrud.SelectMany(command); })); odThread.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => { })); //Do nothing odThread.Name = "bugsGetByVersionThread"; odThread.Start(true); if (!odThread.Join(THREAD_TIMEOUT)) { return(null); } return((List <Bug>)odThread.Tag); }
///<summary>Returns a fully formatted string of the most recent unreleased versions, from 1 to 3.</summary> public static string GetLastReleases(int versionsRequested) { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetString(MethodBase.GetCurrentMethod(), versionsRequested)); } //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 = ""; if (releaseList.Count > 2 && versionsRequested > 2) { versionsString += releaseList[2].MajorNum.ToString() + "." + releaseList[2].MinorNum.ToString() + "." + releaseList[2].BuildNum.ToString() + ".0"; } if (releaseList.Count > 1 && versionsRequested > 1) { if (versionsString != "") { versionsString += ";"; } versionsString += releaseList[1].MajorNum.ToString() + "." + releaseList[1].MinorNum.ToString() + "." + releaseList[1].BuildNum.ToString() + ".0"; } if (releaseList.Count > 0) { if (versionsString != "") { versionsString += ";"; } versionsString += releaseList[0].MajorNum.ToString() + "." + releaseList[0].MinorNum.ToString() + "." + releaseList[0].BuildNum.ToString() + ".0"; } 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() ?? ""); //if either odThread or odThread.Tag is null, return empty string }
private void FillGridWebSchedTimeSlotsThreaded() { if (this.InvokeRequired) { this.BeginInvoke((Action) delegate() { FillGridWebSchedTimeSlotsThreaded(); }); return; } //Validate time slot settings. if (textWebSchedDateStart.errorProvider1.GetError(textWebSchedDateStart) != "") { //Don't bother warning the user. It will just be annoying. The red indicator should be sufficient. return; } if (comboWebSchedRecallTypes.SelectedIndex < 0 || comboWebSchedClinic.SelectedIndex < 0 || comboWebSchedProviders.SelectedIndex < 0) { return; } //Protect against re-entry if (_threadFillGridWebSchedTimeSlots != null) { //A thread is already refreshing the time slots grid so we simply need to queue up another refresh once the one thread has finished. _isWebSchedTimeSlotsOutdated = true; return; } _isWebSchedTimeSlotsOutdated = false; DateTime dateStart = PIn.Date(textWebSchedDateStart.Text); RecallType recallType = _listRecallTypes[comboWebSchedRecallTypes.SelectedIndex]; Clinic clinic = _listWebSchedClinics.Find(x => x.ClinicNum == _webSchedClinicNum); //null clinic is treated as unassigned. List <Provider> listProviders = new List <Provider>(_listWebSchedProviders); //Use all providers by default. Provider provider = _listWebSchedProviders.Find(x => x.ProvNum == _webSchedProvNum); if (provider != null) { //Only use the provider that the user picked from the provider picker. listProviders = new List <Provider>() { provider }; } WebSchedTimeSlotArgs webSchedTimeSlotArgs = new WebSchedTimeSlotArgs() { RecallTypeCur = recallType, ClinicCur = clinic, DateStart = dateStart, DateEnd = dateStart.AddDays(30), ListProviders = listProviders }; _threadFillGridWebSchedTimeSlots = new ODThread(GetWebSchedTimeSlotsWorker, webSchedTimeSlotArgs); _threadFillGridWebSchedTimeSlots.Name = "ThreadWebSchedRecallTimeSlots"; _threadFillGridWebSchedTimeSlots.AddExitHandler(GetWebSchedTimeSlotsThreadExitHandler); _threadFillGridWebSchedTimeSlots.AddExceptionHandler(GetWebSchedTimeSlotsExceptionHandler); _threadFillGridWebSchedTimeSlots.Start(true); }
///<summary>The following test calls setDb within a child thread. This will change the static database connection for all threads. The ///parent thread, or any other thread already alive, should not have their context changed.</summary> public void ODThread_SetDb_ChildContext() { Exception ex = null; string methodName = MethodBase.GetCurrentMethod().Name; string databaseName = POut.String(methodName).ToLower(); string odThreadGroupName = methodName + "_GroupName"; string databaseMain = LargeTableHelper.GetCurrentDatabase(); //should be pointing to a 'unittestXXX' database Assert.IsFalse(string.IsNullOrEmpty(databaseMain)); try { ODThread odThreadAffect = new ODThread((o) => { string databaseBefore = LargeTableHelper.GetCurrentDatabase(); //should be pointing to a 'unittestXXX' database Assert.AreEqual(databaseMain, databaseBefore); ODThread odThreadChangeDb = new ODThread(workerChild => { //The parent thread needs to call SetDb on a different database than the main thread is connected to. CreateDatabaseIfNeeded(databaseName); new DataConnection().SetDb("localhost", databaseName, "root", "", "", "", DatabaseType.MySql); VerifyCurrentDatabaseName(databaseName); }); odThreadChangeDb.AddExceptionHandler(e => ex = e); odThreadChangeDb.Name = MethodBase.GetCurrentMethod().Name + "_Child"; odThreadChangeDb.GroupName = odThreadGroupName; //This thread needs to only start the above thread and then make sure it is still connected to the unittestXXX database when complete. odThreadChangeDb.Start(); odThreadChangeDb.Join(Timeout.Infinite); //Manually join the parent to the main thread so that we know for certain that our child thread exists. VerifyCurrentDatabaseName(databaseMain); }); odThreadAffect.AddExceptionHandler(e => ex = e); odThreadAffect.Name = MethodBase.GetCurrentMethod().Name + "_ThreadAffected"; odThreadAffect.Start(); odThreadAffect.Join(Timeout.Infinite); //The main thread should still be on the original database after this. VerifyCurrentDatabaseName(databaseMain); //Verify that new thread is not affected by the call to SetDb() from the child thread above. //You should only SetDb() once per application instance. //After that, it does nothing to any thread (existing or subsequent) but the thread that calls it. ODThread odThreadChangeDb1 = new ODThread(workerChild => { VerifyCurrentDatabaseName(databaseMain); }); odThreadChangeDb1.AddExceptionHandler(e => ex = e); odThreadChangeDb1.Name = MethodBase.GetCurrentMethod().Name + "_Child"; odThreadChangeDb1.GroupName = odThreadGroupName; odThreadChangeDb1.Start(); odThreadChangeDb1.Join(Timeout.Infinite); //Manually join the parent to the main thread so that we know for certain that our child thread exists. } 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. }
///<summary>Adds an exception handler to the thread passed in, starts the thread, and then waits until the thread has finished executing. ///This is just a helper method that will throw any exception that occurs within the thread on the parent (usually main) thread. ///Throws exceptions.</summary> private static void ExecuteThread(ODThread thread) { Exception eFinal = null; thread.AddExceptionHandler((e) => { eFinal = e; }); thread.Start(true); //This is intended to be a blocking call so give the action as long as it needs to complete. thread.Join(Timeout.Infinite); if (eFinal != null) //We are back on the main thread so it is safe to throw. { throw new Exception(eFinal.Message, eFinal); } }
///<summary>Start a thread dedicated to filling the given cache.</summary> private static void FillCacheThreaded <T>(DashboardCacheBase <T> cache, DashboardFilter filter, string groupName, bool invalidateFirst) { ODThread thread = new ODThread(new ODThread.WorkerDelegate((ODThread th) => { if (OnSetDb != null) { OnSetDb(cache, new EventArgs()); } cache.Run(filter, invalidateFirst); })); thread.GroupName = groupName; thread.Start(false); }
///<summary>Spawns a child thread, on which it sets a Userod object to the thread's value for Security.CurUser.</summary> public static Userod GetCurUserFromThread() { if (RemotingClient.RemotingRole == RemotingRole.ClientWeb) { return(Meth.GetObject <Userod>(MethodBase.GetCurrentMethod())); } Userod user = null; ODThread thread = new ODThread((o) => { user = Security.CurUser; }); thread.Start(); thread.Join(1000); //Give the thread 1 second to finish so this test doesn't hang. return(user); }
///<summary>Shows the saved manually label for 1.5 seconds.</summary> private void ShowManualSaveLabel() { labelSavedManually.Visible = true; ODThread odThread = new ODThread((o) => { Thread.Sleep((int)TimeSpan.FromSeconds(1.5).TotalMilliseconds); this.InvokeIfNotDisposed(() => { labelSavedManually.Visible = false; }); }); odThread.AddExceptionHandler((e) => e.DoNothing()); odThread.Start(); }
///<summary>Runs the workerDelegate on a separate thread and displays a progress window while the thread is running.</summary> public static void ShowProgressForThread(ODThread.WorkerDelegate workerDelegate, Control parent, string startingMessage = "Please Wait...", ProgBarStyle progStyle = ProgBarStyle.Blocks, string threadName = "ODProgressThread", ODThread.ExceptionDelegate exceptionHandler = null) { ODProgress prog = new ODProgress(Lan.g(parent, startingMessage), progStyle); ODThread thread = new ODThread(workerDelegate); if (exceptionHandler != null) { thread.AddExceptionHandler(exceptionHandler); } thread.Name = threadName; thread.ProgressLog = prog; thread.Start(true); prog.ShowDialog(parent); }
///<summary>Starts the thread which will populate the graph's data. DB context should be set before calling this method.</summary> /// <param name="forceCacheRefesh">Will pass this flag along to the thread which retrieves the cache. If true then cache will be invalidated and re-initialiazed from the db. Use sparingly.</param> /// <param name="onException">Exception handler if something fails. If not set then all exceptions will be swallowed.</param> /// <param name="onThreadDone">Done event handler. Will be invoked when init thread has completed.</param> private void Init(bool forceCacheRefesh = false, ODThread.ExceptionDelegate onException = null, EventHandler onThreadDone = null) { if (_thread != null) { return; } if (onThreadDone == null) { onThreadDone = new EventHandler(delegate(object o, EventArgs e) { }); } if (onException == null) { onException = new ODThread.ExceptionDelegate((Exception e) => { }); } _thread = new ODThread(new ODThread.WorkerDelegate((ODThread x) => { //The thread may have run and return before the window is even ready to display. if (this.IsHandleCreated) { OnThreadStartLocal(this, new EventArgs()); } else { this.HandleCreated += OnThreadStartLocal; } //Alert caller that it's time to start querying the db. OnInit(forceCacheRefesh); })); _thread.Name = "GraphQuantityFilterOverTime.Init"; _thread.AddExceptionHandler(onException); _thread.AddExitHandler(new ODThread.WorkerDelegate((ODThread x) => { try { _thread = null; //The thread may have run and return before the window is even ready to display. if (this.IsHandleCreated) { OnThreadExitLocal(this, new EventArgs()); } else { this.HandleCreated += OnThreadExitLocal; } //Alert caller that db querying is done. onThreadDone(this, new EventArgs()); } catch (Exception) { } })); _thread.Start(true); }
private void LoadDataAsync() { ODThread thread = new ODThread((o) => { _listBugsAll = Bugs.GetAll(); this.BeginInvoke((Action)(FillGridMain)); }); thread.AddExceptionHandler((ex) => { try { this.BeginInvoke((Action)(() => { MessageBox.Show(ex.Message); })); } catch { } }); thread.Start(true); }
private void FillGridInsPlanFiles() { gridInsPlanFiles.BeginUpdate(); if (gridInsPlanFiles.ListGridColumns.Count == 0) { gridInsPlanFiles.ListGridColumns.Add(new UI.GridColumn("FileName", 300, UI.GridSortingStrategy.StringCompare)); _colDateIndex = gridInsPlanFiles.ListGridColumns.Count; gridInsPlanFiles.ListGridColumns.Add(new UI.GridColumn("Date", 80, UI.GridSortingStrategy.StringCompare)); _colPatCountIndex = gridInsPlanFiles.ListGridColumns.Count; gridInsPlanFiles.ListGridColumns.Add(new UI.GridColumn("PatCount", 80, UI.GridSortingStrategy.AmountParse)); _colPlanCountIndex = gridInsPlanFiles.ListGridColumns.Count; gridInsPlanFiles.ListGridColumns.Add(new UI.GridColumn("PlanCount", 80, UI.GridSortingStrategy.AmountParse)); _colErrorIndex = gridInsPlanFiles.ListGridColumns.Count; gridInsPlanFiles.ListGridColumns.Add(new UI.GridColumn("Errors", 0, UI.GridSortingStrategy.StringCompare)); } gridInsPlanFiles.ListGridRows.Clear(); gridInsPlanFiles.EndUpdate(); if (!Directory.Exists(textImportPath.Text)) { return; } gridInsPlanFiles.BeginUpdate(); _arrayImportFilePaths = Directory.GetFiles(textImportPath.Text); for (int i = 0; i < _arrayImportFilePaths.Length; i++) { UI.GridRow row = new UI.GridRow(); gridInsPlanFiles.ListGridRows.Add(row); string filePath = _arrayImportFilePaths[i]; row.Tag = filePath; string fileName = Path.GetFileName(filePath); row.Cells.Add(fileName); //FileName row.Cells.Add(""); //Date - This value will be filled in when WorkerParse834() runs below. row.Cells.Add(""); //PatCount - This value will be filled in when WorkerParse834() runs below. row.Cells.Add(""); //PlanCount - This value will be filled in when WorkerParse834() runs below. row.Cells.Add("Loading file..."); //Errors - This value will be filled in when WorkerParse834() runs below. } gridInsPlanFiles.EndUpdate(); Application.DoEvents(); if (_odThread != null) { _odThread.QuitSync(0); } _odThread = new ODThread(WorkerParse834); _odThread.Start(); }
private void RunTransfer() { //Get data from the source connection. This will have all the patients selected from the sourceconnection string stringFailedConns = ""; ODThread odThread = new ODThread(GetDataFromSourceConnection, new object[] { _sourceConnection }); odThread.GroupName = "FetchSheets"; odThread.Start(); ODThread.JoinThreadsByGroupName(Timeout.Infinite, "FetchSheets"); if (_listSheetsForSelectedPats.IsNullOrEmpty()) { string connString = CentralConnections.GetConnectionString(_sourceConnection); stringFailedConns += connString + "\r\n"; } //Insert the sheets to each of the databases. The sheets will have a patnum=0; List <Action> listActions = new List <Action>(); object locker = new object(); foreach (CentralConnection conn in _listConnectionsToTransferTo) { List <Sheet> listSheets = _listSheetsForSelectedPats.Select(x => x.Copy()).ToList(); listActions.Add(() => { if (!InsertSheetsToConnection(conn, listSheets)) { string connString = CentralConnections.GetConnectionString(conn); lock (locker) { stringFailedConns += connString + "\r\n"; } } }); } ODThread.RunParallel(listActions); if (stringFailedConns != "") { stringFailedConns = Lans.g(this, "There were some transfers that failed due to connection issues. Fix connections and try again.\r\n" + "Failed Connections:") + "\r\n" + stringFailedConns; CodeBase.MsgBoxCopyPaste msgBoxCP = new CodeBase.MsgBoxCopyPaste(stringFailedConns); msgBoxCP.ShowDialog(); } else { MsgBox.Show(this, "Transfers Completed Successfully\r\nGo to each database you transferred patients to and retrieve Webforms to finish the " + "transfer process."); } }
///<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. }
///<summary>Launches a splash screen with a progressbar that will listen specifically for ODEvents with the passed in name. ///Returns an ODProgressWindow that has a Close method that should be invoked whenever the progress window should close. ///eventName should be set to the name of the ODEvents that this specific progress window should be processing.</summary> ///<param name="currentForm">The form to activate once the progress is done. If you cannot possibly pass in a form, it is okay to pass in null. ///</param> public static ODProgressWindow ShowProgressSplash(string eventName, Form currentForm) { //Create a splash form with a progress bar on a separate thread to avoid UI lockups bool isFormClosed = false; FormSplash FormS = new FormSplash(eventName); FormS.FormClosed += new FormClosedEventHandler((obj, e) => { isFormClosed = true; }); ODThread odThread = new ODThread(new ODThread.WorkerDelegate((ODThread o) => { //From this point forward, the only way to kill FormSplash is with a DEFCON 1 message via an ODEvent with the corresponding eventName. FormS.ShowDialog(); })); odThread.SetApartmentState(ApartmentState.STA); odThread.AddExceptionHandler(new ODThread.ExceptionDelegate((Exception e) => { })); //Do nothing. odThread.Name = "ProgressSplashThread_" + eventName; odThread.Start(true); return(new ODProgressWindow(new Action(() => { //For progress threads, there is a race condition where the DEFCON 1 event will not get processed. //This is due to the fact that it took the thread longer to instantiate FormProgressStatus than it took the calling method to invoke this action. //Since we don't have access to FormProgressStatus within the thread from here, we simply flag odThread's Tag so that it knows to die. if (odThread != null) { odThread.Tag = true; } //Send the phrase that closes the window in case it is processing events. SplashProgressEvent.Fire(new ODEventArgs(eventName, "DEFCON 1")); if (currentForm != null) { //When the form closed on the other thread it was sometimes causing the application to go behind other applications. Calling Activate() //brings the application back to the front or causes it to flash in the taskbar. DateTime start = DateTime.Now; while (!isFormClosed && (DateTime.Now - start).TotalSeconds < 1) //Wait till the form is closed or for one second { Thread.Sleep(1); } if (!currentForm.IsDisposed) { currentForm.Activate(); } } }))); }