///<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> 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 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); }
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>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 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(); }
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)); } }
///<summary>Retreives new signals from the DB, updates Caches, and broadcasts signals to all subscribed forms.</summary> public static void SignalsTick(Action onShutdown, Action <List <ISignalProcessor>, List <Signalod> > onProcess, Action onDone) { //No need to check RemotingRole; no call to db. Logger.LogToPath("", LogPath.Signals, LogPhase.Start); List <Signalod> listSignals = new List <Signalod>(); ODThread threadRefreshSignals = new ODThread(new ODThread.WorkerDelegate((o) => { //Get new signals from DB. Logger.LogToPath("RefreshTimed", LogPath.Signals, LogPhase.Start); listSignals = RefreshTimed(SignalLastRefreshed); Logger.LogToPath("RefreshTimed", LogPath.Signals, LogPhase.End); //Only update the time stamp with signals retreived from the DB. Do NOT use listLocalSignals to set timestamp. if (listSignals.Count > 0) { SignalLastRefreshed = listSignals.Max(x => x.SigDateTime); } Logger.LogToPath("Found " + listSignals.Count.ToString() + " signals", LogPath.Signals, LogPhase.Unspecified); if (listSignals.Count == 0) { return; } Logger.LogToPath("Signal count(s)", LogPath.Signals, LogPhase.Unspecified, string.Join(" - ", listSignals.GroupBy(x => x.IType).Select(x => x.Key.ToString() + ": " + x.Count()))); if (listSignals.Exists(x => x.IType == InvalidType.ShutDownNow)) { onShutdown(); return; } List <Signalod> listFeeSignals = listSignals.FindAll(x => x.IType == InvalidType.Fees && x.FKeyType == KeyType.FeeSched && x.FKey > 0); if (listFeeSignals.Count > 0) { Fees.InvalidateFeeSchedules(listFeeSignals.Select(x => x.FKey).ToList()); } InvalidType[] cacheRefreshArray = listSignals.FindAll(x => x.FKey == 0 && x.FKeyType == KeyType.Undefined).Select(x => x.IType).Distinct().ToArray(); //Always process signals for ClientDirect users regardless of where the RemoteRole source on the signal is from. //The middle tier server will have refreshed its cache already. bool getCacheFromDb = true; if (RemotingClient.RemotingRole == RemotingRole.ClientWeb && !listSignals.Any(x => x.RemoteRole == RemotingRole.ClientDirect)) { //ClientWebs do not need to tell the middle tier to go to the database unless a ClientDirect has inserted a signal. getCacheFromDb = false; } Cache.Refresh(getCacheFromDb, cacheRefreshArray); onProcess(_listISignalProcessors, listSignals); })); threadRefreshSignals.AddExceptionHandler(new ODThread.ExceptionDelegate((e) => { DateTime dateTimeRefreshed; try { //Signal processing should always use the server's time. dateTimeRefreshed = MiscData.GetNowDateTime(); } catch { //If the server cannot be reached, we still need to move the signal processing forward so use local time as a fail-safe. dateTimeRefreshed = DateTime.Now; } SignalLastRefreshed = dateTimeRefreshed; })); threadRefreshSignals.AddExitHandler(new ODThread.WorkerDelegate((o) => { Logger.LogToPath("", LogPath.Signals, LogPhase.End); onDone(); })); threadRefreshSignals.Name = "SignalsTick"; threadRefreshSignals.Start(true); }
private void FillGridWebSchedNewPatApptTimeSlotsThreaded() { if (this.InvokeRequired) { this.BeginInvoke((Action) delegate() { FillGridWebSchedNewPatApptTimeSlotsThreaded(); }); return; } if (comboWSNPADefApptType.GetSelected <Def>() == null) { if (tabControl.SelectedTab == tabWebSched && tabControlWebSched.SelectedTab == tabWebSchedNewPatAppts) { MsgBox.Show(this, "Set a Web Sched New Pat Appt Type in Definitions to show appointment time slots."); } return; } //Clear the current grid rows before starting the thread below. This allows that thread to exit at any time without leaving old rows in the grid. gridWebSchedNewPatApptTimeSlots.BeginUpdate(); gridWebSchedNewPatApptTimeSlots.ListGridRows.Clear(); gridWebSchedNewPatApptTimeSlots.EndUpdate(); //Validate time slot settings. if (textWebSchedNewPatApptsDateStart.errorProvider1.GetError(textWebSchedNewPatApptsDateStart) != "") { //Don't bother warning the user. It will just be annoying. The red indicator should be sufficient. return; } if (!PrefC.HasClinicsEnabled) { comboWSNPClinics.SelectedIndex = 0; //Not visible but this will set the combo box the "N/A" which is the non-clinic signup } if (comboWSNPClinics.SelectedIndex < 0) { return; //Nothing to do. } WebServiceMainHQProxy.EServiceSetup.SignupOut.SignupOutEService signup = ((ODBoxItem <WebServiceMainHQProxy.EServiceSetup.SignupOut.SignupOutEService>)comboWSNPClinics.SelectedItem).Tag; //Protect against re-entry if (_threadFillGridWebSchedNewPatApptTimeSlots != 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. _isWebSchedNewPatApptTimeSlotsOutdated = true; return; } _isWebSchedNewPatApptTimeSlotsOutdated = false; _indexLastNewPatURL = comboWSNPClinics.SelectedIndex; DateTime dateStart = PIn.DateT(textWebSchedNewPatApptsDateStart.Text); DateTime dateEnd = dateStart.AddDays(30); if (!signup.IsEnabled) { return; //Do nothing, this clinic is excluded from New Pat Appts. } //Only get time slots for headquarters or clinics that are NOT excluded (aka included). var args = new { ClinicNum = signup.ClinicNum, DateStart = dateStart, DateEnd = dateStart.AddDays(30), DefApptType = comboWSNPADefApptType.GetSelected <Def>(), }; _threadFillGridWebSchedNewPatApptTimeSlots = new ODThread(new ODThread.WorkerDelegate((th) => { //The user might not have Web Sched ops set up correctly. Don't warn them here because it is just annoying. They'll figure it out. ODException.SwallowAnyException(() => { //Get the next 30 days of open time schedules with the current settings List <TimeSlot> listTimeSlots = TimeSlots.GetAvailableNewPatApptTimeSlots(args.DateStart, args.DateEnd, args.ClinicNum , args.DefApptType.DefNum); FillGridWebSchedNewPatApptTimeSlots(listTimeSlots); }); })) { Name = "ThreadWebSchedNewPatApptTimeSlots" }; _threadFillGridWebSchedNewPatApptTimeSlots.AddExitHandler(new ODThread.WorkerDelegate((th) => { _threadFillGridWebSchedNewPatApptTimeSlots = null; //If something else wanted to refresh the grid while we were busy filling it then we need to refresh again. A filter could have changed. if (_isWebSchedNewPatApptTimeSlotsOutdated) { FillGridWebSchedNewPatApptTimeSlotsThreaded(); } })); _threadFillGridWebSchedNewPatApptTimeSlots.Start(true); }