/// <summary> /// Sets data to database. /// </summary> protected void btnOK_Click(object sender, EventArgs e) { // Check "modify" permission if (!MembershipContext.AuthenticatedUser.IsAuthorizedPerResource("CMS.ScheduledTasks", "Modify")) { RedirectToAccessDenied("CMS.ScheduledTasks", "Modify"); } // Check required fields format string errorMessage = new Validator() .NotEmpty(txtTaskDisplayName.Text, rfvDisplayName.ErrorMessage) .NotEmpty(txtTaskName.Text, rfvName.ErrorMessage) .IsCodeName(txtTaskName.Text, GetString("Task_Edit.InvalidTaskName")) .MatchesCondition(schedInterval.StartTime.SelectedDateTime, DataTypeManager.IsValidDate, String.Format("{0} {1}.", GetString("BasicForm.ErrorInvalidDateTime"), DateTime.Now)) .Result; if ((errorMessage == String.Empty) && !schedInterval.CheckIntervalPreceedings()) { errorMessage = GetString("Task_Edit.BetweenIntervalPreceedingsError"); } if ((errorMessage == String.Empty) && !schedInterval.CheckOneDayMinimum()) { errorMessage = GetString("Task_Edit.AtLeastOneDayError"); } // Validate assembly, but only if task is enabled (so tasks for not-installed modules can be disabled) if ((errorMessage == String.Empty) && chkTaskEnabled.Checked && !assemblyElem.IsValid()) { errorMessage = assemblyElem.ErrorMessage; } // Checking date/time limit (SQL limit) if (errorMessage == String.Empty) { TaskInterval ti = SchedulingHelper.DecodeInterval(schedInterval.ScheduleInterval); if ((ti != null) && ((ti.StartTime < DataTypeManager.MIN_DATETIME) || (ti.StartTime > DataTypeManager.MAX_DATETIME))) { ti.StartTime = DateTime.Now; schedInterval.ScheduleInterval = SchedulingHelper.EncodeInterval(ti); } } // Check macro condition length if ((errorMessage == String.Empty) && (ucMacroEditor.Text.Length > 400)) { errorMessage = String.Format(GetString("task_edit.invalidlength"), 400); } if (!String.IsNullOrEmpty(errorMessage)) { ShowError(errorMessage); } else { // Check existing task name TaskInfo existingTask = TaskInfoProvider.GetTaskInfo(txtTaskName.Text.Trim(), SiteInfo != null ? SiteInfo.SiteName : null); if ((existingTask != null) && ((TaskInfo == null) || (existingTask.TaskID != TaskInfo.TaskID))) { ShowError(GetString("Task_Edit.TaskNameExists").Replace("%%name%%", existingTask.TaskName)); return; } if (TaskInfo == null) { // create new item -> insert TaskInfo = new TaskInfo { TaskSiteID = SiteID }; if (!developmentMode) { TaskInfo.TaskAllowExternalService = true; } } TaskInfo.TaskAssemblyName = assemblyElem.AssemblyName.Trim(); TaskInfo.TaskClass = assemblyElem.ClassName.Trim(); TaskInfo.TaskData = txtTaskData.Text.Trim(); TaskInfo.TaskName = txtTaskName.Text.Trim(); TaskInfo.TaskEnabled = chkTaskEnabled.Checked; TaskInfo.TaskDeleteAfterLastRun = chkTaskDeleteAfterLastRun.Checked; TaskInfo.TaskInterval = schedInterval.ScheduleInterval; TaskInfo.TaskDisplayName = txtTaskDisplayName.Text.Trim(); TaskInfo.TaskServerName = txtServerName.Text.Trim(); TaskInfo.TaskRunInSeparateThread = chkRunTaskInSeparateThread.Checked; TaskInfo.TaskUseExternalService = chkTaskUseExternalService.Checked; TaskInfo.TaskCondition = ucMacroEditor.Text; TaskInfo.TaskRunIndividuallyForEachSite = chkRunIndividually.Checked; if (plcAllowExternalService.Visible) { TaskInfo.TaskAllowExternalService = chkTaskAllowExternalService.Checked; } if (plcUseExternalService.Visible) { TaskInfo.TaskUseExternalService = chkTaskUseExternalService.Checked; } TaskInfo.TaskNextRunTime = SchedulingHelper.GetFirstRunTime(SchedulingHelper.DecodeInterval(TaskInfo.TaskInterval)); if (drpModule.Visible) { TaskInfo.TaskResourceID = ValidationHelper.GetInteger(drpModule.Value, 0); } TaskInfo.TaskUserID = ValidationHelper.GetInteger(ucUser.Value, 0); // Set synchronization to true (default is false for Scheduled task) TaskInfo.Generalized.StoreSettings(); TaskInfo.Generalized.LogSynchronization = SynchronizationTypeEnum.LogSynchronization; TaskInfo.Generalized.LogIntegration = true; TaskInfo.Generalized.LogEvents = true; // If web farm support, create the tasks for all servers if (chkAllServers.Checked) { TaskInfoProvider.CreateWebFarmTasks(TaskInfo); } else { TaskInfoProvider.SetTaskInfo(TaskInfo); } // Restore original settings TaskInfo.Generalized.RestoreSettings(); bool notSystem = (TaskInfo == null) || (TaskInfo.TaskType != ScheduledTaskTypeEnum.System); string url = UIContextHelper.GetElementUrl("CMS.ScheduledTasks", GetElementName(notSystem ? "EditTask" : "EditSystemTask"), true); // Add task ID and saved="1" query parameters url = URLHelper.AddParameterToUrl(String.Format(url, TaskInfo.TaskID), "saved", "1"); // Add site ID query parameter and redirect to the finished URL URLHelper.Redirect(URLHelper.AddParameterToUrl(url, "siteid", SiteID.ToString())); } }
/// <summary> /// Handles the UniGrid's OnAction event. /// </summary> /// <param name="actionName">Name of item (button) that threw event</param> /// <param name="actionArgument">ID (value of Primary key) of corresponding data row</param> protected void gridElem_OnAction(string actionName, object actionArgument) { switch (actionName.ToLowerCSafe()) { case "edit": if (!String.IsNullOrEmpty(EditURL)) { URLHelper.Redirect(String.Format(EditURL, actionArgument)); } break; case "delete": { // Check "modify" permission if (!MembershipContext.AuthenticatedUser.IsAuthorizedPerResource("CMS.ScheduledTasks", "Modify")) { RedirectToAccessDenied("CMS.ScheduledTasks", "Modify"); } // Delete the task try { int taskId = Convert.ToInt32(actionArgument); TaskInfo ti = TaskInfoProvider.GetTaskInfo(taskId); if (ti != null) { ti.Generalized.LogSynchronization = SynchronizationTypeEnum.LogSynchronization; ti.Generalized.LogIntegration = true; ti.Generalized.LogEvents = true; TaskInfoProvider.DeleteTaskInfo(ti); } } catch (Exception ex) { ShowError(GetString("Task_List.DeleteError"), ex.Message); } } break; case "execute": { // Check "modify" permission if (!MembershipContext.AuthenticatedUser.IsAuthorizedPerResource("CMS.ScheduledTasks", "Modify")) { RedirectToAccessDenied("CMS.ScheduledTasks", "Modify"); } TaskInfo ti = TaskInfoProvider.GetTaskInfo(Convert.ToInt32(actionArgument)); if (ti != null) { SiteInfo si = SiteInfoProvider.GetSiteInfo(SiteID); if (!ti.TaskEnabled) { // Task is not enabled (won't be executed at the end of request), run it now SchedulingExecutor.ExecuteTask(ti.TaskID, (si != null) ? si.SiteName : SiteContext.CurrentSiteName); } else { TaskInterval interval = SchedulingHelper.DecodeInterval(ti.TaskInterval); if ((ti.TaskNextRunTime != DateTimeHelper.ZERO_TIME) || (interval.Period == SchedulingHelper.PERIOD_ONCE)) { ti.TaskNextRunTime = DateTime.Now; // Update the task TaskInfoProvider.SetTaskInfo(ti); // Run the task SchedulingTimer.RunSchedulerImmediately = true; if (si != null) { SchedulingTimer.SchedulerRunImmediatelySiteName = si.SiteName; } } else { ShowWarning(GetString("ScheduledTask.TaskAlreadyrunning")); return; } } ShowConfirmation(GetString("ScheduledTask.WasExecuted")); } } break; } }
/// <summary> /// Saves the control. Returns false, if error occurred. /// </summary> public bool Save() { // Validates input data String error = ValidateData(); if (!String.IsNullOrEmpty(error)) { ShowError(error); return(false); } if (Report != null) { bool isNew = false; if (mReportSubscriptionInfo.ReportSubscriptionID <= 0) { // Insert mode - initialize reportSubscriptionID mReportSubscriptionInfo.ReportSubscriptionUserID = MembershipContext.AuthenticatedUser.UserID; mReportSubscriptionInfo.ReportSubscriptionSiteID = SiteContext.CurrentSiteID; mReportSubscriptionInfo.ReportSubscriptionSettings["ReportInterval"] = mIntervalStr; isNew = true; } if (!SimpleMode) { // Save basic form & validates basic form data if (!formElem.SaveData(null)) { return(false); } // Store all parameters in basic form to string XML representation mParameters = formElem.DataRow; mReportSubscriptionInfo.ReportSubscriptionValueID = 0; mReportSubscriptionInfo.ReportSubscriptionTableID = 0; mReportSubscriptionInfo.ReportSubscriptionGraphID = 0; // If subscription is not for whole report, store item ID string drpValue = drpItems.SelectedValue; if (drpValue != "all") { int id = ValidationHelper.GetInteger(drpValue.Substring(1), 0); if (drpValue.Contains('g')) { mReportSubscriptionInfo.ReportSubscriptionGraphID = id; } if (drpValue.Contains('t')) { mReportSubscriptionInfo.ReportSubscriptionTableID = id; } if (drpValue.Contains('v')) { mReportSubscriptionInfo.ReportSubscriptionValueID = id; } } } else { mReportSubscriptionInfo.ReportSubscriptionGraphID = mGraphID; mReportSubscriptionInfo.ReportSubscriptionTableID = mTableID; mReportSubscriptionInfo.ReportSubscriptionValueID = mValueID; } if (mParameters != null) { // Find special 'from' and 'to' parameters. DataColumn dcFrom = mParameters.Table.Columns["fromdate"]; DataColumn dcTo = mParameters.Table.Columns["todate"]; if (rbTime.Checked) { if (dcTo != null) { // Convert column from datetime to string to enable store macros mParameters.Table.Columns.Remove(dcTo.ColumnName); mParameters.Table.Columns.Add(dcTo.ColumnName, typeof(String)); // Add current date time macro mParameters[dcTo.ColumnName] = "{%CurrentDateTime%}"; } // Create right macro datetime command based on given interval. String command = String.Empty; switch (drpLast.SelectedValue) { case "hour": command = "AddHours"; break; case "day": command = "AddDays"; break; case "week": command = "AddWeeks"; break; case "month": command = "AddMonths"; break; case "year": command = "AddYears"; break; } // Create todate macro int last = ValidationHelper.GetInteger(txtLast.Text.Trim(), 0); String dateCommand = String.Format("{{%CurrentDateTime.{0}({1})%}}", command, last * (-1)); // Convert fromdate to string if (dcFrom != null) { mParameters.Table.Columns.Remove(dcFrom.ColumnName); mParameters.Table.Columns.Add(dcFrom.ColumnName, typeof(String)); mParameters[dcFrom.ColumnName] = dateCommand; } } else { // Empty fromdate and todate for uncheck limit date if (dcFrom != null) { mParameters[dcFrom.ColumnName] = DBNull.Value; } if (dcTo != null) { mParameters[dcTo.ColumnName] = DBNull.Value; } } // Write parameters to XML string representation mReportSubscriptionInfo.ReportSubscriptionParameters = ReportHelper.WriteParametersToXml(mParameters); } String email = txtEmail.Text.Trim(); bool emailChanged = mReportSubscriptionInfo.ReportSubscriptionEmail != email; mReportSubscriptionInfo.ReportSubscriptionEnabled = chkEnabled.Checked; mReportSubscriptionInfo.ReportSubscriptionReportID = Report.ReportID; mReportSubscriptionInfo.ReportSubscriptionInterval = ucInterval.ScheduleInterval; mReportSubscriptionInfo.ReportSubscriptionEmail = email; mReportSubscriptionInfo.ReportSubscriptionSubject = txtSubject.Text; mReportSubscriptionInfo.ReportSubscriptionCondition = ucMacroEditor.Text; mReportSubscriptionInfo.ReportSubscriptionOnlyNonEmpty = chkNonEmpty.Checked; mReportSubscriptionInfo.ReportSubscriptionNextPostDate = SchedulingHelper.GetFirstRunTime(ucInterval.TaskInterval); ReportSubscriptionInfoProvider.SetReportSubscriptionInfo(mReportSubscriptionInfo); // Check whether email changed (applies for new subscription also) if (emailChanged) { String siteName = SiteContext.CurrentSiteName; EmailTemplateInfo eti = EmailTemplateProvider.GetEmailTemplate("Reporting_Subscription_information", siteName); if (eti != null) { // Send information email EmailMessage em = new EmailMessage(); em.EmailFormat = EmailFormatEnum.Default; em.From = String.IsNullOrEmpty(eti.TemplateFrom) ? EmailHelper.Settings.NotificationsSenderAddress(siteName) : eti.TemplateFrom; em.Recipients = email; em.Subject = eti.TemplateSubject; em.BccRecipients = eti.TemplateBcc; em.CcRecipients = eti.TemplateCc; MacroResolver resolver = ReportSubscriptionSender.CreateSubscriptionMacroResolver(Report, mReportSubscriptionInfo, SiteContext.CurrentSite, em.Recipients); em.Body = resolver.ResolveMacros(eti.TemplateText); em.PlainTextBody = resolver.ResolveMacros(eti.TemplatePlainText); EmailHelper.ResolveMetaFileImages(em, eti.TemplateID, EmailTemplateInfo.OBJECT_TYPE, ObjectAttachmentsCategories.TEMPLATE); EmailSender.SendEmail(siteName, em); } } // For new item and advanced mode redirect to store ID in query string if ((isNew) && (!SimpleMode)) { URLHelper.Redirect(RequestContext.CurrentURL + "&saved=1&subscriptionid=" + mReportSubscriptionInfo.ReportSubscriptionID); } ShowChangesSaved(); return(true); } return(false); }
/// <summary> /// Creates schedule interval string. /// </summary> protected override string EncodeInterval() { if (!TimeoutEnabled) { return(String.Empty); } TaskInterval ti = new TaskInterval(); string result = string.Empty; try { ti.Period = Mode; if (Mode != SchedulingHelper.PERIOD_ONCE) { result = new Validator().NotEmpty(txtQuantity.Text, GetString("timeoutselector.quantity.errorempty")).IsInteger(txtQuantity.Text, String.Format(GetString("timeoutselector.quantity.wrongformat"), QUANTITYMAXIMUM)).Result; if (String.IsNullOrEmpty(result)) { int quantity = ValidationHelper.GetInteger(txtQuantity.Text, -1); if ((quantity >= QuantityLowerBound) && (quantity <= QUANTITYMAXIMUM)) { ti.Every = quantity; } else { txtQuantity.ForeColor = Color.Red; } } } if (String.IsNullOrEmpty(result)) { switch (Mode) { case SchedulingHelper.PERIOD_MINUTE: case SchedulingHelper.PERIOD_HOUR: case SchedulingHelper.PERIOD_DAY: ti.BetweenStart = DateTime.MinValue; ti.BetweenEnd = DateTime.MaxValue; // Add all days to match the format AddWeekDays(ti); AddWeekEnd(ti); break; case SchedulingHelper.PERIOD_WEEK: if (rbNextDay.Checked) { ti.Order = drpNextOrder.SelectedValue; ti.Day = drpNextDay.SelectedValue; } break; case SchedulingHelper.PERIOD_MONTH: if (rbNextDate.Checked) { ti.Order = drpNextDate.SelectedValue; } else if (rbNextDay.Checked) { ti.Order = drpNextOrder.SelectedValue; ti.Day = drpNextDay.SelectedValue; } break; case SchedulingHelper.PERIOD_YEAR: if (rbNextDate.Checked) { ti.Order = drpNextDateMonth.SelectedValue; ti.Day = drpNextDate.SelectedValue; } break; case SchedulingHelper.PERIOD_ONCE: if (dateTimePicker.SelectedDateTime != DateTime.MinValue) { ti.StartTime = dateTimePicker.SelectedDateTime; } else { result = GetString("timeoutselector.errorinvaliddate"); } break; } // Add specific time to start date if (String.IsNullOrEmpty(result) && cbSpecificTime.Visible && cbSpecificTime.Checked) { //result = new Validator().NotEmpty(txtSpecificTimeHour.Text, GetString("timeoutselector.specifichour.errorempty")).IsInteger(txtSpecificTimeHour.Text, GetString("timeoutselector.specifichour.wrongformat")).NotEmpty(txtSpecificTimeMinute.Text, GetString("timeoutselector.specificminute.errorempty")).IsInteger(txtSpecificTimeMinute.Text, GetString("timeoutselector.specificminute.wrongformat")).Result; if (timePicker.IsValid()) { ti.StartTime = ti.StartTime.AddHours(timePicker.Time.Hour); ti.StartTime = ti.StartTime.AddMinutes(timePicker.Time.Minute); ti.UseSpecificTime = true; } else { result = timePicker.ErrorMessage; } } else { ti.UseSpecificTime = false; } } } catch (Exception ex) { ShowError(ex.Message); result = ex.Message; dateTimePicker.DateTimeTextBox.ForeColor = Color.Red; } if (!String.IsNullOrEmpty(result)) { AddError(result); return(null); } WeekListChecked = true; return(SchedulingHelper.EncodeInterval(ti)); }
/// <summary> /// Saves configuration changes. /// </summary> protected void SaveData() { // Check "configure" permission if (!CMSContext.CurrentUser.IsAuthorizedPerResource("cms.newsletter", "configure")) { RedirectToCMSDeskAccessDenied("cms.newsletter", "configure"); } string scheduledInterval = null; if (isDynamic && chkSchedule.Checked) { // Get scheduled interval for dynamic newsletter scheduledInterval = schedulerInterval.ScheduleInterval; } string errorMessage = ValidateNewsletterValues(); if (!string.IsNullOrEmpty(errorMessage)) { ShowError(errorMessage); return; } NewsletterInfo newsletterObj = NewsletterInfoProvider.GetNewsletterInfo(txtNewsletterName.Text.Trim(), CMSContext.CurrentSiteID); // Newsletter's code name must be unique if (newsletterObj != null && newsletterObj.NewsletterID != newsletterId) { ShowError(GetString("Newsletter_Edit.NewsletterNameExists")); return; } if (newsletterObj == null) { newsletterObj = NewsletterInfoProvider.GetNewsletterInfo(newsletterId); } SetNewsletterValues(newsletterObj); // Check if subscription template was selected int subscriptionTemplateValue = ValidationHelper.GetInteger(subscriptionTemplate.Value, 0); if (subscriptionTemplateValue == 0) { ShowError(GetString("Newsletter_Edit.NoSubscriptionTemplateSelected")); return; } newsletterObj.NewsletterSubscriptionTemplateID = subscriptionTemplateValue; // Check if double opt-in template was selected int optInTemplateValue = ValidationHelper.GetInteger(optInSelector.Value, 0); if (newsletterObj.NewsletterEnableOptIn && optInTemplateValue == 0) { ShowError(GetString("Newsletter_Edit.NoOptInTemplateSelected")); return; } newsletterObj.NewsletterOptInTemplateID = optInTemplateValue; // Check if unsubscription template was selected int unsubscriptionTemplateValue = ValidationHelper.GetInteger(unsubscriptionTemplate.Value, 0); if (unsubscriptionTemplateValue == 0) { ShowError(GetString("Newsletter_Edit.NoUnsubscriptionTemplateSelected")); return; } newsletterObj.NewsletterUnsubscriptionTemplateID = unsubscriptionTemplateValue; // ID of scheduled task which should be deleted int deleteScheduledTaskId = 0; if (isDynamic) { newsletterObj.NewsletterType = NewsletterType.Dynamic; newsletterObj.NewsletterDynamicURL = txtNewsletterDynamicURL.Text.Trim(); newsletterObj.NewsletterDynamicSubject = radFollowing.Checked ? txtSubject.Text : string.Empty; if (chkSchedule.Checked) { // Set info for scheduled task TaskInfo task = GetDynamicNewsletterTask(newsletterObj); if (!schedulerInterval.CheckOneDayMinimum()) { // If problem occurred while setting schedule interval ShowError(GetString("Newsletter_Edit.NoDaySelected")); return; } if (!IsValidDate(SchedulingHelper.DecodeInterval(scheduledInterval).StartTime)) { ShowError(GetString("Newsletter.IncorrectDate")); return; } task.TaskInterval = scheduledInterval; task.TaskNextRunTime = SchedulingHelper.GetNextTime(task.TaskInterval, new DateTime(), new DateTime()); task.TaskDisplayName = GetString("DynamicNewsletter.TaskName") + newsletterObj.NewsletterDisplayName; task.TaskName = "DynamicNewsletter_" + newsletterObj.NewsletterName; // Set task for processing in external service task.TaskAllowExternalService = true; task.TaskUseExternalService = (SchedulingHelper.UseExternalService && NewsletterHelper.UseExternalServiceForDynamicNewsletters(CMSContext.CurrentSiteName)); TaskInfoProvider.SetTaskInfo(task); newsletterObj.NewsletterDynamicScheduledTaskID = task.TaskID; } else { if (newsletterObj.NewsletterDynamicScheduledTaskID > 0) { // Store task ID for deletion deleteScheduledTaskId = newsletterObj.NewsletterDynamicScheduledTaskID; } newsletterObj.NewsletterDynamicScheduledTaskID = 0; schedulerInterval.Visible = false; } } else { newsletterObj.NewsletterType = NewsletterType.TemplateBased; // Check if issue template was selected int issueTemplateValue = ValidationHelper.GetInteger(issueTemplate.Value, 0); if (issueTemplateValue == 0) { ShowError(GetString("Newsletter_Edit.NoEmailTemplateSelected")); return; } newsletterObj.NewsletterTemplateID = issueTemplateValue; } // Save changes to DB NewsletterInfoProvider.SetNewsletterInfo(newsletterObj); if (deleteScheduledTaskId > 0) { // Delete scheduled task if schedule mail-outs were unchecked TaskInfoProvider.DeleteTaskInfo(deleteScheduledTaskId); } ShowChangesSaved(); // Refresh header with display name ScriptHelper.RefreshTabHeader(Page, GetString("Newsletter_Header.Configuration")); }
public async Task ActivationSched_Task_Run_Delay() { using var workItemGroup = SchedulingHelper.CreateWorkItemGroupForTesting(context, loggerFactory); TaskScheduler scheduler = workItemGroup.TaskScheduler; ManualResetEvent pause1 = new ManualResetEvent(false); ManualResetEvent pause2 = new ManualResetEvent(false); var finish = new TaskCompletionSource <bool>(); Task <int> task1 = null; Task <int> task2 = null; Task join = null; Task wrapper = new Task(() => { task1 = Task.Run(() => { this.output.WriteLine("Task-1 Started"); Assert.NotEqual(scheduler, TaskScheduler.Current); Task.Delay(1); Assert.NotEqual(scheduler, TaskScheduler.Current); pause1.WaitOne(); this.output.WriteLine("Task-1 Done"); return(1); }); task2 = Task.Run(() => { this.output.WriteLine("Task-2 Started"); Assert.NotEqual(scheduler, TaskScheduler.Current); Task.Delay(1); Assert.NotEqual(scheduler, TaskScheduler.Current); pause2.WaitOne(); this.output.WriteLine("Task-2 Done"); return(2); }); join = Task.WhenAll(task1, task2).ContinueWith(t => { this.output.WriteLine("Join Started"); if (t.IsFaulted) { throw t.Exception; } Assert.Equal(scheduler, TaskScheduler.Current); this.output.WriteLine("Join Done"); }); finish.SetResult(true); }); wrapper.Start(scheduler); var timeoutLimit = TimeSpan.FromSeconds(1); try { await finish.Task.WithTimeout(timeoutLimit); } catch (TimeoutException) { Assert.True(false, "Result did not arrive before timeout " + timeoutLimit); } pause1.Set(); pause2.Set(); Assert.NotNull(join); // Joined promise assigned await join; Assert.True(join.IsCompleted && !join.IsFaulted, "Join Status " + join); Assert.True(task1.IsCompleted && !task1.IsFaulted, "Task-1 Status " + task1); Assert.True(task2.IsCompleted && !task2.IsFaulted, "Task-2 Status " + task2); }
public async Task ActivationSched_Turn_Execution_Order_Loop() { using var workItemGroup = SchedulingHelper.CreateWorkItemGroupForTesting(context, loggerFactory); TaskScheduler scheduler = workItemGroup.TaskScheduler; const int NumChains = 100; const int ChainLength = 3; // Can we add a unit test that basicaly checks that any turn is indeed run till completion before any other turn? // For example, you have a long running main turn and in the middle it spawns a lot of short CWs (on Done promise) and StartNew. // You test that no CW/StartNew runs until the main turn is fully done. And run in stress. var resultHandles = new TaskCompletionSource <bool> [NumChains]; Task[] taskChains = new Task[NumChains]; Task[] taskChainEnds = new Task[NumChains]; bool[] executingChain = new bool[NumChains]; int[] stageComplete = new int[NumChains]; int executingGlobal = -1; for (int i = 0; i < NumChains; i++) { int chainNum = i; // Capture int sleepTime = ThreadSafeRandom.Next(100); resultHandles[i] = new TaskCompletionSource <bool>(); taskChains[i] = new Task(() => { const int taskNum = 0; try { Assert.Equal(-1, executingGlobal); // "Detected unexpected other execution in chain " + chainNum + " Task " + taskNum Assert.False(executingChain[chainNum], "Detected unexpected other execution on chain " + chainNum + " Task " + taskNum); executingGlobal = chainNum; executingChain[chainNum] = true; Thread.Sleep(sleepTime); } finally { stageComplete[chainNum] = taskNum; executingChain[chainNum] = false; executingGlobal = -1; } }); Task task = taskChains[i]; for (int j = 1; j < ChainLength; j++) { int taskNum = j; // Capture task = task.ContinueWith(t => { if (t.IsFaulted) { throw t.Exception; } this.output.WriteLine("Inside Chain {0} Task {1}", chainNum, taskNum); try { Assert.Equal(-1, executingGlobal); // "Detected unexpected other execution in chain " + chainNum + " Task " + taskNum Assert.False(executingChain[chainNum], "Detected unexpected other execution on chain " + chainNum + " Task " + taskNum); Assert.Equal(taskNum - 1, stageComplete[chainNum]); // "Detected unexpected execution stage on chain " + chainNum + " Task " + taskNum executingGlobal = chainNum; executingChain[chainNum] = true; Thread.Sleep(sleepTime); } finally { stageComplete[chainNum] = taskNum; executingChain[chainNum] = false; executingGlobal = -1; } }, scheduler); } taskChainEnds[chainNum] = task.ContinueWith(t => { if (t.IsFaulted) { throw t.Exception; } this.output.WriteLine("Inside Chain {0} Final Task", chainNum); resultHandles[chainNum].SetResult(true); }, scheduler); } for (int i = 0; i < NumChains; i++) { taskChains[i].Start(scheduler); } for (int i = 0; i < NumChains; i++) { TimeSpan waitCheckTime = TimeSpan.FromMilliseconds(150 * ChainLength * NumChains * WaitFactor); try { await resultHandles[i].Task.WithTimeout(waitCheckTime); } catch (TimeoutException) { Assert.True(false, "Result did not arrive before timeout " + waitCheckTime); } bool ok = resultHandles[i].Task.Result; try { // since resultHandle being complete doesn't directly imply that the final chain was completed (there's a chance for a race condition), give a small chance for it to complete. await taskChainEnds[i].WithTimeout(TimeSpan.FromMilliseconds(10)); } catch (TimeoutException) { Assert.True(false, $"Task chain end {i} should complete very shortly after after its resultHandle"); } Assert.True(taskChainEnds[i].IsCompleted, "Task chain " + i + " should be completed"); Assert.False(taskChainEnds[i].IsFaulted, "Task chain " + i + " should not be Faulted: " + taskChainEnds[i].Exception); Assert.Equal(ChainLength - 1, stageComplete[i]); // "Task chain " + i + " should have completed all stages" Assert.True(ok, "Successfully waited for ResultHandle for Task chain " + i); } }
/// <summary> /// Saves configuration changes. /// </summary> protected void SaveData() { // Check "configure" permission if (!MembershipContext.AuthenticatedUser.IsAuthorizedPerResource("cms.newsletter", "configure")) { RedirectToAccessDenied("cms.newsletter", "configure"); } string scheduledInterval = null; if (isDynamic && chkSchedule.Checked) { // Get scheduled interval for dynamic newsletter scheduledInterval = schedulerInterval.ScheduleInterval; } string errorMessage = ValidateNewsletterValues(); if (!string.IsNullOrEmpty(errorMessage)) { ShowError(errorMessage); return; } NewsletterInfo newsletterObj = NewsletterInfoProvider.GetNewsletterInfo(txtNewsletterName.Text.Trim(), SiteContext.CurrentSiteID); // Newsletter's code name must be unique if (newsletterObj != null && newsletterObj.NewsletterID != EditedNewsletter.NewsletterID) { ShowError(GetString("Newsletter_Edit.NewsletterNameExists")); return; } if (newsletterObj == null) { newsletterObj = NewsletterInfoProvider.GetNewsletterInfo(EditedNewsletter.NewsletterID); } SetNewsletterValues(newsletterObj); // Check if subscription template was selected int subscriptionTemplateValue = ValidationHelper.GetInteger(subscriptionTemplate.Value, 0); if (EditedFeedIsNewsletter() && subscriptionTemplateValue == 0) { ShowError(GetString("Newsletter_Edit.NoSubscriptionTemplateSelected")); return; } newsletterObj.NewsletterSubscriptionTemplateID = subscriptionTemplateValue; // Check if double opt-in template was selected if (chkEnableOptIn.Checked) { int optInTemplateValue = ValidationHelper.GetInteger(optInSelector.Value, 0); if (optInTemplateValue == 0) { ShowError(GetString("Newsletter_Edit.NoOptInTemplateSelected")); return; } newsletterObj.NewsletterOptInTemplateID = optInTemplateValue; } else { newsletterObj.NewsletterOptInTemplateID = 0; } // Check if unsubscription template was selected int unsubscriptionTemplateValue = ValidationHelper.GetInteger(unsubscriptionTemplate.Value, 0); if (unsubscriptionTemplateValue == 0) { ShowError(GetString("Newsletter_Edit.NoUnsubscriptionTemplateSelected")); return; } newsletterObj.NewsletterUnsubscriptionTemplateID = unsubscriptionTemplateValue; // ID of scheduled task which should be deleted int deleteScheduledTaskId = 0; if (isDynamic) { newsletterObj.NewsletterSource = NewsletterSource.Dynamic; newsletterObj.NewsletterDynamicURL = txtNewsletterDynamicURL.Value.ToString(); newsletterObj.NewsletterDynamicSubject = radFollowing.Checked ? txtSubject.Text : string.Empty; if ((String.IsNullOrEmpty(txtNewsletterDynamicURL.Value.ToString()))) { // Dynamic URL cannot be empty ShowError(GetString("newsletter_edit.sourcepageurlempty")); return; } if (chkSchedule.Checked) { if (!schedulerInterval.CheckOneDayMinimum()) { // If problem occurred while setting schedule interval ShowError(GetString("Newsletter_Edit.NoDaySelected")); return; } TaskInterval taskInterval = SchedulingHelper.DecodeInterval(scheduledInterval); if (!DataTypeManager.IsValidDate(taskInterval.StartTime)) { ShowError(GetString("Newsletter.IncorrectDate")); return; } UpdateDynamicNewsletterTask(newsletterObj, taskInterval); } else { if (newsletterObj.NewsletterDynamicScheduledTaskID > 0) { // Store task ID for deletion deleteScheduledTaskId = newsletterObj.NewsletterDynamicScheduledTaskID; } newsletterObj.NewsletterDynamicScheduledTaskID = 0; schedulerInterval.Visible = false; } } else { newsletterObj.NewsletterSource = NewsletterSource.TemplateBased; // Check if at least one template is selected if (string.IsNullOrEmpty(ValidationHelper.GetString(usTemplates.Value, null))) { ShowError(GetString("Newsletter_Edit.NoEmailTemplateSelected")); usTemplates.Value = mCurrentTemplates; return; } SaveTemplates(); } // Save changes to DB NewsletterInfoProvider.SetNewsletterInfo(newsletterObj); if (deleteScheduledTaskId > 0) { // Delete scheduled task if schedule mail-outs were unchecked TaskInfoProvider.DeleteTaskInfo(deleteScheduledTaskId); } ShowChangesSaved(); // Update breadcrumbs ScriptHelper.RefreshTabHeader(Page, newsletterObj.NewsletterDisplayName); }
public async Task ActivationSched_WhenAny_Busy_Timeout() { using var workItemGroup = SchedulingHelper.CreateWorkItemGroupForTesting(context, loggerFactory); TaskScheduler scheduler = workItemGroup.TaskScheduler; var pause1 = new TaskCompletionSource <bool>(); var pause2 = new TaskCompletionSource <bool>(); var finish = new TaskCompletionSource <bool>(); Task <int> task1 = null; Task <int> task2 = null; Task join = null; Task wrapper = new Task(() => { task1 = Task <int> .Factory.StartNew(() => { this.output.WriteLine("Task-1 Started"); Assert.Equal(scheduler, TaskScheduler.Current); int num1 = 1; while (!pause1.Task.Result) // Infinite busy loop { num1 = ThreadSafeRandom.Next(); } this.output.WriteLine("Task-1 Done"); return(num1); }); task2 = Task <int> .Factory.StartNew(() => { this.output.WriteLine("Task-2 Started"); Assert.Equal(scheduler, TaskScheduler.Current); int num2 = 2; while (!pause2.Task.Result) // Infinite busy loop { num2 = ThreadSafeRandom.Next(); } this.output.WriteLine("Task-2 Done"); return(num2); }); join = Task.WhenAny(task1, task2, Task.Delay(TimeSpan.FromSeconds(2))); finish.SetResult(true); }); wrapper.Start(scheduler); var timeoutLimit = TimeSpan.FromSeconds(1); try { await finish.Task.WithTimeout(timeoutLimit); } catch (TimeoutException) { Assert.True(false, "Result did not arrive before timeout " + timeoutLimit); } Assert.NotNull(join); // Joined promise assigned await join; Assert.True(join.IsCompleted && !join.IsFaulted, "Join Status " + join.Status); Assert.False(task1.IsFaulted, "Task-1 Faulted " + task1.Exception); Assert.False(task1.IsCompleted, "Task-1 Status " + task1.Status); Assert.False(task2.IsFaulted, "Task-2 Faulted " + task2.Exception); Assert.False(task2.IsCompleted, "Task-2 Status " + task2.Status); }
/// <summary> /// OnAfterSave event handler. /// </summary> protected void EditForm_OnAfterSave(object sender, EventArgs e) { // Get edited contact group ContactGroupInfo cgi = (ContactGroupInfo)EditForm.EditedObject; if (chkDynamic.Checked) { // Set info for scheduled task task = GetScheduledTask(cgi); // Update scheduled task if (chkSchedule.Checked) { if (!schedulerInterval.CheckOneDayMinimum()) { // If problem occurred while setting schedule interval EditForm.ErrorLabel.Text = GetString("Newsletter_Edit.NoDaySelected"); EditForm.ErrorLabel.Visible = true; EditForm.StopProcessing = true; return; } if (!IsValidDate(SchedulingHelper.DecodeInterval(scheduleInterval).StartTime)) { // Start date is not in valid format EditForm.ErrorLabel.Text = GetString("Newsletter.IncorrectDate"); EditForm.ErrorLabel.Visible = true; EditForm.StopProcessing = true; return; } task.TaskInterval = scheduleInterval; task.TaskNextRunTime = SchedulingHelper.GetNextTime(task.TaskInterval, new DateTime(), new DateTime()); task.TaskEnabled = true; } else { task.TaskInterval = scheduleInterval; task.TaskNextRunTime = TaskInfoProvider.NO_TIME; task.TaskEnabled = false; } TaskInfoProvider.SetTaskInfo(task); cgi.ContactGroupScheduledTaskID = task.TaskID; pnlInfo.Visible = true; InitInfoPanel(cgi, true); } else { if (cgi.ContactGroupScheduledTaskID > 0) { // Store task ID for deletion deleteScheduledTaskId = cgi.ContactGroupScheduledTaskID; } cgi.ContactGroupScheduledTaskID = 0; cgi.ContactGroupStatus = ContactGroupStatusEnum.Unspecified; schedulerInterval.Visible = false; pnlInfo.Visible = false; } // Update contact group ContactGroupInfoProvider.SetContactGroupInfo(cgi); if (deleteScheduledTaskId > 0) { // Delete scheduled task if schedule evaluation was unchecked TaskInfoProvider.DeleteTaskInfo(deleteScheduledTaskId); } InitHeaderActions(false); ((CMSPage)Page).CurrentMaster.HeaderActions.ReloadData(); // Refresh breadcrumbs after data are loaded ScriptHelper.RefreshTabHeader(Page, null); }
public void Sched_Task_SchedulingContext() { var context = new UnitTestSchedulingContext(); using var workItemGroup = SchedulingHelper.CreateWorkItemGroupForTesting(context, loggerFactory); context.Scheduler = workItemGroup; var result = new TaskCompletionSource <bool>(); Task endOfChain = null; int n = 0; Task wrapper = new Task(() => { CheckRuntimeContext(context); // ReSharper disable AccessToModifiedClosure Task task1 = Task.Factory.StartNew(() => { this.output.WriteLine("===> 1a "); CheckRuntimeContext(context); Thread.Sleep(1000); n = n + 3; this.output.WriteLine("===> 1b"); CheckRuntimeContext(context); }); Task task2 = task1.ContinueWith(task => { this.output.WriteLine("===> 2"); CheckRuntimeContext(context); n = n * 5; }); Task task3 = task2.ContinueWith(task => { this.output.WriteLine("===> 3"); n = n / 5; CheckRuntimeContext(context); }); Task task4 = task3.ContinueWith(task => { this.output.WriteLine("===> 4"); n = n - 2; result.SetResult(true); CheckRuntimeContext(context); }); // ReSharper restore AccessToModifiedClosure endOfChain = task4.ContinueWith(task => { this.output.WriteLine("Done Faulted={0}", task.IsFaulted); CheckRuntimeContext(context); Assert.False(task.IsFaulted, "Faulted with Exception=" + task.Exception); }); }); wrapper.Start(workItemGroup.TaskScheduler); bool ok = wrapper.Wait(TimeSpan.FromSeconds(1)); if (!ok) { throw new TimeoutException(); } Assert.False(wrapper.IsFaulted, "Wrapper Task Faulted with Exception=" + wrapper.Exception); Assert.True(wrapper.IsCompleted, "Wrapper Task completed"); bool finished = result.Task.Wait(TimeSpan.FromSeconds(2)); Assert.NotNull(endOfChain); // End of chain Task created successfully Assert.False(endOfChain.IsFaulted, "Task chain Faulted with Exception=" + endOfChain.Exception); Assert.True(finished, "Wrapper Task completed ok"); Assert.True(n != 0, "Work items did not get executed"); Assert.Equal(1, n); // "Work items executed out of order" }
public void Sched_AC_Current_TaskScheduler() { UnitTestSchedulingContext context = new UnitTestSchedulingContext(); var workItemGroup = SchedulingHelper.CreateWorkItemGroupForTesting(context, loggerFactory); context.Scheduler = workItemGroup; ActivationTaskScheduler activationScheduler = workItemGroup.TaskScheduler; this.mainDone = false; var result = new TaskCompletionSource <bool>(); Task wrapper = null; Task finalPromise = null; context.Scheduler.QueueAction(() => { Log(1, "Outer ClosureWorkItem " + Task.CurrentId + " starting"); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #0" Log(2, "Starting wrapper Task"); wrapper = Task.Factory.StartNew(() => { Log(3, "Inside wrapper Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" Log(4, "Wrapper Task " + Task.CurrentId + " creating AC chain"); Task promise1 = Task.Factory.StartNew(() => { Log(5, "#1 Inside AC Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" SubProcess1(1); }); Task promise2 = promise1.ContinueWith((_) => { Log(6, "#2 Inside AC Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #2" SubProcess1(2); }); finalPromise = promise2.ContinueWith((_) => { Log(7, "#3 Inside final AC Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #3" SubProcess1(3); result.SetResult(true); }); finalPromise.Ignore(); Log(8, "Wrapper Task Id=" + Task.CurrentId + " sleeping"); Thread.Sleep(TimeSpan.FromSeconds(1)); Log(9, "Wrapper Task Id=" + Task.CurrentId + " finished"); }); Log(10, "Outer ClosureWorkItem Task Id=" + Task.CurrentId + " sleeping"); Thread.Sleep(TimeSpan.FromSeconds(1)); Log(11, "Outer ClosureWorkItem Task Id=" + Task.CurrentId + " awake"); Log(12, "Finished Outer TaskWorkItem Task Id=" + wrapper.Id); this.mainDone = true; }); Log(13, "Waiting for ClosureWorkItem to spawn wrapper Task"); for (int i = 0; i < 5 * WaitFactor; i++) { if (wrapper != null) { break; } Thread.Sleep(TimeSpan.FromSeconds(1).Multiply(WaitFactor)); } Assert.NotNull(wrapper); // Wrapper Task was not created Log(14, "Waiting for wrapper Task Id=" + wrapper.Id + " to complete"); bool finished = wrapper.Wait(TimeSpan.FromSeconds(4 * WaitFactor)); Log(15, "Done waiting for wrapper Task Id=" + wrapper.Id + " Finished=" + finished); if (!finished) { throw new TimeoutException(); } Assert.False(wrapper.IsFaulted, "Wrapper Task faulted: " + wrapper.Exception); Assert.True(wrapper.IsCompleted, "Wrapper Task should be completed"); Log(16, "Waiting for TaskWorkItem to complete"); for (int i = 0; i < 15 * WaitFactor; i++) { if (this.mainDone) { break; } Thread.Sleep(1000 * WaitFactor); } Log(17, "Done waiting for TaskWorkItem to complete MainDone=" + this.mainDone); Assert.True(this.mainDone, "Main Task should be completed"); Assert.NotNull(finalPromise); // AC chain not created Log(18, "Waiting for final AC promise to complete"); finalPromise.Wait(TimeSpan.FromSeconds(4 * WaitFactor)); Log(19, "Done waiting for final promise"); Assert.False(finalPromise.IsFaulted, "Final AC faulted: " + finalPromise.Exception); Assert.True(finalPromise.IsCompleted, "Final AC completed"); Assert.True(result.Task.Result, "Timeout-1"); Assert.NotEqual(0, this.stageNum1); // "Work items did not get executed-1" Assert.Equal(3, this.stageNum1); // "Work items executed out of order-1" }
public void Sched_Task_Turn_Execution_Order() { // A unit test that checks that any turn is indeed run till completion before any other turn? // For example, you have a long running main turn and in the middle it spawns a lot of short CWs (on Done promise) and StartNew. // You test that no CW/StartNew runs until the main turn is fully done. And run in stress. UnitTestSchedulingContext context = new UnitTestSchedulingContext(); WorkItemGroup workItemGroup = SchedulingHelper.CreateWorkItemGroupForTesting(context, this.loggerFactory); context.Scheduler = workItemGroup; ActivationTaskScheduler activationScheduler = workItemGroup.TaskScheduler; this.mainDone = false; this.stageNum1 = this.stageNum2 = 0; var result1 = new TaskCompletionSource <bool>(); var result2 = new TaskCompletionSource <bool>(); Task wrapper = null; Task finalTask1 = null; Task finalPromise2 = null; context.Scheduler.QueueAction(() => { Log(1, "Outer ClosureWorkItem " + Task.CurrentId + " starting"); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #0" Log(2, "Starting wrapper Task"); wrapper = Task.Factory.StartNew(() => { Log(3, "Inside wrapper Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #1" // Execution chain #1 Log(4, "Wrapper Task Id=" + Task.CurrentId + " creating Task chain"); Task task1 = Task.Factory.StartNew(() => { Log(5, "#11 Inside sub-Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #11" SubProcess1(11); }); Task task2 = task1.ContinueWith((Task task) => { Log(6, "#12 Inside continuation Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #12" if (task.IsFaulted) { throw task.Exception.Flatten(); } SubProcess1(12); }); Task task3 = task2.ContinueWith(task => { Log(7, "#13 Inside continuation Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #13" if (task.IsFaulted) { throw task.Exception.Flatten(); } SubProcess1(13); }); finalTask1 = task3.ContinueWith(task => { Log(8, "#14 Inside final continuation Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #14" if (task.IsFaulted) { throw task.Exception.Flatten(); } SubProcess1(14); result1.SetResult(true); }); // Execution chain #2 Log(9, "Wrapper Task " + Task.CurrentId + " creating AC chain"); Task promise2 = Task.Factory.StartNew(() => { Log(10, "#21 Inside sub-Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #21" SubProcess2(21); }); finalPromise2 = promise2.ContinueWith((_) => { Log(11, "#22 Inside final continuation Task Id=" + Task.CurrentId); Assert.Equal(activationScheduler, TaskScheduler.Current); // "TaskScheduler.Current #22" SubProcess2(22); result2.SetResult(true); }); finalPromise2.Ignore(); Log(12, "Wrapper Task Id=" + Task.CurrentId + " sleeping #2"); Thread.Sleep(TimeSpan.FromSeconds(1)); Log(13, "Wrapper Task Id=" + Task.CurrentId + " finished"); }); Log(14, "Outer ClosureWorkItem Task Id=" + Task.CurrentId + " sleeping"); Thread.Sleep(TimeSpan.FromSeconds(1)); Log(15, "Outer ClosureWorkItem Task Id=" + Task.CurrentId + " awake"); Log(16, "Finished Outer ClosureWorkItem Task Id=" + wrapper.Id); this.mainDone = true; }); Log(17, "Waiting for ClosureWorkItem to spawn wrapper Task"); for (int i = 0; i < 5 * WaitFactor; i++) { if (wrapper != null) { break; } Thread.Sleep(TimeSpan.FromSeconds(1).Multiply(WaitFactor)); } Assert.NotNull(wrapper); // Wrapper Task was not created Log(18, "Waiting for wrapper Task Id=" + wrapper.Id + " to complete"); bool finished = wrapper.Wait(TimeSpan.FromSeconds(4 * WaitFactor)); Log(19, "Done waiting for wrapper Task Id=" + wrapper.Id + " Finished=" + finished); if (!finished) { throw new TimeoutException(); } Assert.False(wrapper.IsFaulted, "Wrapper Task faulted: " + wrapper.Exception); Assert.True(wrapper.IsCompleted, "Wrapper Task should be completed"); Log(20, "Waiting for TaskWorkItem to complete"); for (int i = 0; i < 15 * WaitFactor; i++) { if (this.mainDone) { break; } Thread.Sleep(1000 * WaitFactor); } Log(21, "Done waiting for TaskWorkItem to complete MainDone=" + this.mainDone); Assert.True(this.mainDone, "Main Task should be completed"); Assert.NotNull(finalTask1); // Task chain #1 not created Assert.NotNull(finalPromise2); // Task chain #2 not created Log(22, "Waiting for final task #1 to complete"); bool ok = finalTask1.Wait(TimeSpan.FromSeconds(4 * WaitFactor)); Log(23, "Done waiting for final task #1 complete Ok=" + ok); if (!ok) { throw new TimeoutException(); } Assert.False(finalTask1.IsFaulted, "Final Task faulted: " + finalTask1.Exception); Assert.True(finalTask1.IsCompleted, "Final Task completed"); Assert.True(result1.Task.Result, "Timeout-1"); Log(24, "Waiting for final promise #2 to complete"); finalPromise2.Wait(TimeSpan.FromSeconds(4 * WaitFactor)); Log(25, "Done waiting for final promise #2"); Assert.False(finalPromise2.IsFaulted, "Final Task faulted: " + finalPromise2.Exception); Assert.True(finalPromise2.IsCompleted, "Final Task completed"); Assert.True(result2.Task.Result, "Timeout-2"); Assert.NotEqual(0, this.stageNum1); // "Work items did not get executed-1" Assert.Equal(14, this.stageNum1); // "Work items executed out of order-1" Assert.NotEqual(0, this.stageNum2); // "Work items did not get executed-2" Assert.Equal(22, this.stageNum2); // "Work items executed out of order-2" }
/// <summary> /// Handles the UniGrid's OnAction event. /// </summary> /// <param name="actionName">Name of item (button) that threw event</param> /// <param name="actionArgument">ID (value of Primary key) of corresponding data row</param> protected void gridElem_OnAction(string actionName, object actionArgument) { switch (actionName.ToLowerInvariant()) { case "edit": if (!String.IsNullOrEmpty(EditURL)) { URLHelper.Redirect(UrlResolver.ResolveUrl(String.Format(EditURL, actionArgument))); } break; case "delete": { // Check "modify" permission if (!MembershipContext.AuthenticatedUser.IsAuthorizedPerResource("CMS.ScheduledTasks", "Modify")) { RedirectToAccessDenied("CMS.ScheduledTasks", "Modify"); } // Delete the task try { int taskId = Convert.ToInt32(actionArgument); TaskInfo task = TaskInfo.Provider.Get(taskId); if (task != null) { task.Generalized.LogSynchronization = SynchronizationTypeEnum.LogSynchronization; task.Generalized.LogIntegration = true; task.Generalized.LogEvents = true; TaskInfo.Provider.Delete(task); if (task.TaskType == ScheduledTaskTypeEnum.System) { Service.Resolve <IEventLogService>().LogWarning("ScheduledTasks", "DELETE", $"System scheduled task '{task.TaskName}' has been deleted."); } } } catch (Exception ex) { ShowError(GetString("Task_List.DeleteError"), ex.Message); } } break; case "execute": { // Check "modify" permission if (!MembershipContext.AuthenticatedUser.IsAuthorizedPerResource("CMS.ScheduledTasks", "Modify")) { RedirectToAccessDenied("CMS.ScheduledTasks", "Modify"); } TaskInfo taskInfo = TaskInfo.Provider.Get(Convert.ToInt32(actionArgument)); if (taskInfo != null) { if (taskInfo.TaskIsRunning) { ShowWarning(GetString("ScheduledTask.TaskAlreadyrunning")); return; } var site = SiteInfo.Provider.Get(SiteID); var siteId = site?.SiteID ?? SiteContext.CurrentSiteID; var url = SchedulingUrlFactory.GetSchedulerUrl(siteId, taskInfo.TaskAvailability, taskInfo.TaskID); SchedulingHelper.RunSchedulerRequest(url); ShowConfirmation(GetString("ScheduledTask.WasExecuted")); } } break; } }