Creating a Scheduled Task

Overview

To create a Scheduled Task, in Visual Studio .NET you must create a new Class that is a subclass of Avectra.netForum.TaskManager.TaskFacade, which is a specialized FacadeClass itself. The class must have a public method that will execute the operations of your task. Additionally, you’ll create a new database table that will link to the baseline ts_scheduled_task table and reference this table as a DynamicData in your new class. This table will have one row for each time a task is scheduled. This row can also store run-time parameters entered a user and can also store foreign keys pointing to other records (for example, if you’re creating a task that operates against an event, then you’ll want to store the value of that Event’s evt_key in a xxx_evt_key column). After creating the table, you’ll build a netFORUM Object in the Toolkit, as well as a Form that allows an end user to add and schedule the task as well as to enter any runtime parameters. You’ll create a new Task Type that references your code. The overall Task Scheduler will reference the Task Type definition in order to run your method by reflection.

Once you’ve deployed your work, then end users can start adding and running scheduled tasks.

Database Table

Important! If your task has run-time parameters, then you must create a new database table to record the value(s) of those parameters. If you do not have any run-time parameters, then you do not need to create a table.

Add a new Table using standard netFORUM naming conventions. Ensure that “task” or “scheduler” is in the name of the table to explain its purpose. Do NOT create an extender table since these tasks are not customizable at this time.

In SQL Server Studio, change the name of the primary key column to be xxx_tsk_key instead of xxx_key. In the properties of the column, you’ll need to turn off RowGuid, change the column’s name, save the table, then change RowGuid back to Yes before SQL Server will allow you to do this. Make sure the xxx_tsk_key is Primary Key and not null.

Add any other columns you’ll need that will hold values your Task must execute. This could include a foreign key pointing to a record on which your task will operate, or any run-time parameters entered by the user. You do NOT need to have columns for when the Task should run; that will be handled elsewhere.

Do NOT create a foreign key constraint to the ts_scheduled_task table because a record will get inserted into your table first and then insert a records in the ts_scheduled_task table later.


As shown in the sample table, the column stt_tsk_key holds a tsk_key which will be in the ts_scheduled_task table. The stt_sos_key is a foreign key column that will hold the value of the “parent” record that this task relates to. The code in this task will reference that record and get more information on it. The stt_start_date and stt_end_date columns store the parameter values the user enters when adding the record.

After saving table, run md_privilege_populate_by_table_quick on the table.

Avectra.netForum.Common.dbN

 

Note: this step applies only to baseline netFORUM development.

Update this class with your new table in it; you’ll need it in the next step.

Class

In your .NET Solution, create a new Class file. The Class must be a subclass of Avectra.netForum.TaskManager.TaskFacade. The namespace might be Avectra.netForum.ScheduledTasks (for baseline code). For client code, use those naming conventions.

For convenience, you can make a copy of ScheduledTaskTemplate.cs to get started as this template has stubs for the main segments of code. You’ll need to rename your own class file and update a few other parts in the file to work with your new version. Go through your copied class and look for the TODO notations. To avoid confusing people who will open the source code in the future, we suggest removing those TODO lines once you’ve done them as these can falsely leave the unknowing reader with the unsettling concern that these were not in fact done.

Your class must have a public void method with no parameters that netFORUM’s task scheduler can run by reflection. Inside this method, you will execute the actual code that is your task. See ScheduledTaskTemplate.cs for a sample structure.

The only “rules” that you must follow in your own code is that you should set certain properties in the Avectra.netForum.TaskManager.TaskEventsArgs object as illustrated in the template.

Abila Developers

If this task is being added to baseline netFORUM, then you’ll need to add this Class file to the ScheduledTasks Class Library located in the Scheduling folder of the netFORUM solution.

Client Developers

If you’re developing a Task for a particular client, then you’ll create your own project and add it there. Eventually, you’ll need to deploy that DLL to the bin folder in iWeb so the overall netFORUM Scheduler will be able to access it. You also need to add the .dll to Binaries folder on the root.

Object

In the netFORUM Toolkit, add a new Object for your class. Remember, adding a Scheduled Task is really a lot like adding any other record in netFORUM, and you need an Object for that.

We recommend not running the Object Wizard to do this because it will create metadata you'll need to remove later. Be sure to enter the correct Assembly and Type Name based on the class you created above. For netFORUM baseline development, the assembly will be ScheduledTasks and the type name will be Avectra.netForum.ScheduledTasks.NameOfTheClassYouCreated. If custom, then enter the name of your own assembly and type name. Do not enable Workflow.

If you will allow Task records to be added from the “parent” record then set a related object/control to set the foreign key value in the Task record to be the primary key value of the parent object. If you do this then remember to check the has related objects? checkbox on the object.


You will not need to add Data Objects because you will add them in code in the class file.

Form

If your task has run-time parameters, then you'll need to add an add/edit form to your object. Check the designed checkbox. Design the form and add fields for any parameters the user must enter. If you don't have any runtime parameters, then you can use the baseline Task Facade form for add/edit operations, and you won't need to follow any of the other steps in this section.

Add a label to your form under which you’ll add the fields for scheduling. Change the label's text to l Scheduling and make the class be DataFormChildHeader and widen it to go across the width of the form (this is an Avectra consistent style for all Task forms).

Add a subform control to your form. This subform will point to the baseline task scheduler sub-form that contains core information such as the date and time to run the class. The subform URL/Image Path/Data will be exactly:

DefaultFormKey[d85d13f3-4463-4f74-a678-f8109194c07e], [alwaysupdatepanel]

This FormKey points to an actual form in netFORUM called Task Facade SubForm and is used as a subform for all non-recurring scheduled tasks.

If the Task can be recurring, then use a different FormKey in the subform URL/Image Path/Data. There is one subform for tasks that can be recurring, and a different one for tasks that cannot be recurring. The subform for recurring tasks is:

DefaultFormKey[f21ef63f-e272-4455-ab0d-bfec5172287a], [alwaysupdatepanel]

The subform for recurring tasks is considerably taller so you’ll need to allow more space for it. Make the main form bigger and make the subform size bigger.

Enable User to Add Task

Next, you’ll need to add a UI for a user to create a task, set any parameters that will be supplied to the Task, and schedule it. In most cases, your Task will hang off some “parent” record from which a Task is launched. You could enable a user to create a Task with an icon on that parent record that launches your form in popup, or with a child form accessed from the parent record. For example, if you want to run a scheduled task for an Event, for example, then add an Event child form to allow you to add schedule records.

If you have a Child Form, you might have this form of SQL:

SELECT xxx_tsk_key, 
[Task Name] = tsk_task_name,
[STATUS] = tsk_status,
[Next Execution Date] = tsk_next_exec_date,
[Last Executed Date] = tsk_last_exec_date,
[Another FIELD] = xxx_something
FROM my_scheduler_table (nolock)
JOIN ts_scheduled_task (nolock)
ON tsk_key = xxx_tsk_key
WHERE xxx_zzz_key = {zzz_key}

In the child form, set the GoTo Override to be for the Task Scheduler Profile form and enter xxx_tsk_key as the goto override key. This will allow the user to go to the Task Scheduler Profile page and see the stats for that task. Alternately, you can create your own profile page just to manage the tasks.

Task Scheduler Type

The Task Scheduler Type stores metadata about each scheduled task, such as the description, the namespace and assembly of the class, and which method in the class should be run.

In netFORUM iWeb, go to Admin -> Task Scheduler Type and add a new Task Scheduler Type.

Task Type Name: same as Object Display Name (in most cases, this is the clearest way to associate the Task Type with the Object and avoid naming confusion).

Profile Object - Set the Profile Object to be the Object you created above.

Edit Form - Set the Edit Form to be the Form you created above.

Profile Form - Set the Profile Form to be Task Scheduler Profile (unless you create your own profile page as described in the Task Profile Page section).

Task Timeout - enter the number of seconds the task should run before timing out. Default is 0 which actually means unlimited.

allow recurrence? - If the task can be recurring, be sure to check the “allow recurrence” checkbox. (As described in the Form section you'll still need to design the form differently if the task can be recurring.)

assembly name - enter the assembly; this will be the same as you entered in the Object.

class name - enter the class name; this will be the same as you entered in the Object.

method name - enter the name of the public method in the class.


Refer to existing Task Scheduler Types to get an idea of how the forms work.

After you've saved the record, copy the key from the URL after key= and paste it somewhere because you'll need to put this key into your C# class as the value for the property szTaskTypeKey. This is needed to default the Task Type dropdownlist when adding a new Scheduled Task.

Running Code Locally

Follow these steps to run your code locally so you can step through the code.

Once all your development is complete, go to netFORUM iWeb and add a Scheduled Task. Set it to be one day in the future. After saving the Task, copy its Key from querystring.

Client Development

Class Library

If you do not have a Class Library for netFORUM Component Objects, then create one.

Add references to netFORUM libraries:

  • Common (common.dll)
  • Data (data.dll)
  • Components (Components.dll)
  • TaskManager (TaskManager.dll)

If you have a Class Library for netFORUM Component Objects, then ensure it has the references above.

Class

Add the Class to the Class Library above.

Deploy

Deploy the DLL to the bin folders of the netFORUM servers.

Abila

Go to the netForumStartTask project in the SchedulingFolder, go to Properties, Debug, in command line arguments paste the Key you copied in the earlier step.

Make this project be “Startup Project”, then right-mouse-click, debug, step into new instance, debug, step into new instance.

netForumStartTask will launch as an executable, read in the parameter you pasted, open up the Task Scheduler record for that Key (which is the one you just added), and then launch your code by reflection. You will then be able to step through and debug your code.

FAQ

Q. When I try to add the Task, after I select the Task Type from the DropDownList, I get a C# error about viewstate. Why?

A. You need to set the tsk_ttp_key (Task Scheduler Type key) in code as described in the Task Scheduler Type section of this topic.

Q. I’m changing metadata, but the executable is still working on cached versions when I debug locally.

A. Go here (or wherever you have your solutions mapped) on your own computer:

C:\inetpub\wwwroot\NetForumEP\netForumStartTask\bin

And delete the CacheRoot folder.

Q. Whenever I save a Task, I get an error like:

{"(16,42):EndBoundary:2011-08-20T00:00:00"}

A. Check the value in tsk_end_date. It should be 06/06/2079.