This includes a mechanism to initialize and retrieve the JobID, a common method RunSingleJob to run the job and set the next time to run in the database after a successful run, and an overridable method PerformRunJob to be customized for each individual job.
The flow layer will also need to have job-specific classes built for each job it performs. These will inherit from the base Job class and will override the PerformRunJob function of the Job class to customize the execution of that particular job. Finally, the flow layer will need to be able to determine which jobs need to run, loop through them, and run them. First, let's create the Job base class in the flow layer project, which will be the parent of each individual job class. The core of the Job abstract base class is shown in Figure 5.
It allows the initialization and retrieval of its JobID, as well as ensuring that the database is updated if the job is run successfully. The JobID will not change for a given job after it is created, so you must ensure that after initialization the set function will not change the value. The isInitialized variable is used to make sure that each job has its JobID initialized before running the job. The PerformRunJob abstract method is implemented by derived Job classes and holds the actual logic for the task.
After a job's implementation PerformRunJob method runs successfully, the base class calls the RecordJobSuccess function, which uses the UpdateJobDone method of the Business Logic layer's JobLogic class to record the time that it ran in the database as well as the next scheduled time to run.
I will create the JobLogic class of the Business Logic layer later. The Job class provides both the ability to initialize the JobID variable and to update the database upon success with the next run time. Plus, you only have to override one function with class-specific code. This allows you to create the child classes of the Job class. To do so, you need to create two classes that will run a particular type of job and inherit from the Job class to obtain the rest of their functionality.
Create a JobRunTest class and a JobEmailUsers class and make sure that each one inherits from the Job class, as shown in the following:. Place your job-specific logic inside this method.
The rest of the code that runs the jobs and updates the next run time in the database is inherited from the Job base class. Your jobs will combine calls to the existing Business Logic classes in order to run complex processes. Now that you have the sample jobs, let's look at how to create these jobs using the JobFactory object.
Figure 6 shows the code in the JobFactory. The CreateJob function takes a currentJobID and uses it in a case statement to determine which child class of the Job class should be returned. It then initializes the current JobID and returns the Job-derived class. Now that you have the Job base class, its job-specific children, and a way to select which class to create, you can look at how to pull it all together using the JobFlow class.
To create a class called JobFlow that will gather and execute the appropriate jobs, add a function called "RunAllActiveJobs" to loop through each job that you need to run and call their individual RunSingleJob functions.
You'll need the RunAllActiveJobs function to grab a list of the jobs that are due to run from the database through the business layer, data access layer, and stored procedures, and then run them using their respective RunSingleJob functions. Basically, you would store the jobs in the database with information on the last time that they ran as well as the interval that the code should wait between runs. Each active job's ID is used to get a Job object, whose RunSingleJob method can be used to execute the task as previously described.
Determining which scheduled jobs should be run means that you need to store basic information about them such as the interval between runs, the last time that they ran, and the next time that they should run. The JobID column holds the unique identifier for each job in the job table. The JobTitle column contains the job name so that you can determine which job is being run.
The JobInterval column holds the interval between jobs. The DateLastJobRan column contains a datetime value for the date and time that the job last ran. The last column, DateNextJobStart, contains the next time that the job should run. While this column should be a computed column which is equal to JobInterval plus DateLastJobRan, you can understand the application layers more vividly if you set this up as a regular datetime column.
To retrieve and set job timing information through the new stored procedures in the SQL Server database, the stored procedures must find all of the jobs in the database that need to be run by the application, update a single job's information in the database to indicate that it has run, and set the next job-run date for that job.
Each job has a DateNextJobStart column in the database that indicates the date and time at which the job should run. If the current date and time is past that of the DateNextJobStart column, then the job should be run in the process. The stored procedure that selects the jobs that should be run is shown here:. To find which jobs should run, simply pass in the current date and time through the stored procedure's parameter. Now that you can select the jobs that need to run, you can switch to building the procedure to update them after they run.
The stored procedure that updates the database with a single job's last run date and next run date is as follows:. This procedure should only run after the job referenced in JobID is run and should be called with the DateLastJobRan parameter equal to the date and time that the job ran last. You can extend the data access layer to call the job timing stored procedures by adding a new class called JobAccess.
The role of functions in the data access layer is to translate the parameters passed to it by the business layer into a stored procedure database query and return the result to the business layer. The parameters in the data access layer's functions will mirror those of the stored procedures that they access because they do not perform any Business Logic on the values. This class contains functionality that simplifies data access code, making your code more concise and readable.
To change the data access layer to run the scheduled jobs, first add a JobAccess class to the existing data access layer to hold the functions that are needed to schedule jobs. Making the Windows Service Automatically start after Installation. After the installation one has to start the Windows Service manually through the Services section of My Computer Management. We can start the Windows Service automatically after installation by making use of the AfterInstall event handler which triggers immediately after Windows Service is installed.
You will need to open the ProjectInstaller class and override the AfterInstall event handler and add the code to start the Windows Service. OnAfterInstall savedState ;. ServiceController serviceInstaller1. Start ;. Public Class ProjectInstaller. Public Sub New. OnAfterInstall savedState. ServiceController ServiceInstaller1. Installing the Windows Service using InstallUtil.
Once all the processes are complete, we can now build the Windows Service. Note : Once the Windows Service is ready for deployment, it is recommended to make use of the Release version of the EXE file instead of the Debug version.
Now copy and build the path in a Notepad Text file. Note : I would recommend to build the command in a Notepad and save it somewhere so that you can use it multiple times. InstallUtil Syntax. Note : I am making use of Visual Studio , and hence you need to use the appropriate version installed on your computer.
And make sure you are logged in as Administrator. Without Administrator rights it would not allow you to install the Windows Service. In the command prompt window, copy the InstallUtil command from Notepad and right click in the Command Prompt and click Paste and then press Enter key. Now the Installer will ask for Logon permissions to run the Windows Service and hence you will need to add Windows Username and Password of user who has appropriate permission.
Note : Username must include Domain Name or the Computer name. After successful installation you will see the following message. You can find the Windows Service in the Services window. In order to open Services window in the Run Command type, services. Uninstalling the Windows Service using InstallUtil. The syntax for uninstalling a Windows Service is very similar to the installation syntax. After successful uninstallation you will see the following message.
Related Articles. Add Comments. Thank you for the feedback. The comment is now awaiting moderation. You will be notified via email when the author replies to your comment. Please select a comment to reply. You can add your comment about this article using the form below. Make sure you provide a valid email address else you won't be notified when the author replies to your comment Please note that all comments are moderated and will be deleted if they are Not relavant to the article Spam Advertising campaigns or links to other sites Abusive content.
Please do not post code, scripts or snippets. Required Invalid Email Address. Begin the task : On a schedule Settings : Select the option needed Daily Select the Start : day and time the task will start triggering.
If set for Daily, Weekly or Monthly the time configured will be used for the recurring triggers. You will be prompted to enter user credentials with administrative rights if "Run with highest privileges" was selected. Now click on Task Scheduler Library folder in the left column, verify the schedule has been created and is listed.
Additional Notes. Knowledge Article Total View Count. URL Name. Article Number. Disclaimers Discontinued Product? Electrical Shock Hazard? View All. Sandeep Mishra Updated date Jun 18, In this article, we are going to learn how to call a web API from a windows service at a scheduled time. You can skip this step as this is optional otherwise we can launch the API directly from visual studio and test our API. We will create the project like we did the WebApi, but this time we will select the Windows service template.
Next Recommended Reading. Net Core 6. Create A. Understanding Thread Starvation in.
0コメント