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);
        }
        private void GetWebSchedTimeSlotsWorker(ODThread o)
        {
            WebSchedTimeSlotArgs w             = (WebSchedTimeSlotArgs)o.Parameters[0];
            List <TimeSlot>      listTimeSlots = new List <TimeSlot>();

            try {
                //Get the next 30 days of open time schedules with the current settings
                listTimeSlots = TimeSlots.GetAvailableWebSchedTimeSlots(w.RecallTypeCur, w.ListProviders, w.ClinicCur, w.DateStart, w.DateEnd);
            }
            catch (Exception) {
                //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.
            }
            o.Tag = listTimeSlots;
        }