I've given a task to create an email C# console application which targeted to run as batch. I'm very new to C# area and hence I have no idea about my direction. This C# console application will be deployed on a server and expect to run in certain time based on server time.
After some research, most of the suggestions are about using task scheduler or window services, but I'm wondering if this C# console application is somehow possible to run own its own? Maybe after execute it, it then register itself into the server and the server will handle it periodically?
If you want to manage the scheduler by code have a look at Quartz.NET: http://quartznet.sourceforge.net/
This library provides the creation of jobs and triggers.
e.g. (directly from: http://quartznet.sourceforge.net/tutorial/lesson_3.html):
// construct a scheduler factory
ISchedulerFactory schedFact = new StdSchedulerFactory();
// get a scheduler
IScheduler sched = schedFact.GetScheduler();
sched.Start();
// construct job info
JobDetail jobDetail = new JobDetail("myJob", null, typeof(DumbJob));
// fire every hour
Trigger trigger = TriggerUtils.MakeHourlyTrigger();
// start on the next even hour
trigger.StartTime = TriggerUtils.GetEvenHourDate(DateTime.UtcNow);
trigger.Name = "myTrigger";
sched.ScheduleJob(jobDetail, trigger);
Now this means your console application should run continuously which makes it not really suitable for the job.
Option 1. Add a task via task scheduler (real easy) that executes your console application. See example task: http://www.sevenforums.com/tutorials/12444-task-scheduler-create-new-task.html
Option 2. Create a windows service (not to complicated) that uses a library like Quartz.NET or .NET's Timer class to scheduele jobs and executes a batch operation. See for creation of windows service http://msdn.microsoft.com/en-us/library/zt39148a.aspx
Option 3. Make your console application implement a scheduele library like Quartz.NET or /Net's Timer class and run it as a service (a bit more complex): Create Windows service from executable
As long as it requires no user input, it will be able to run on it's own. You can schedule the program to run in Windows Task Scheduler for example.
Related
I have a Windows Forms application where users can define certain tasks to be scheduled, but I want to run them on another server. I was thinking that I could schedule the tasks using Quartz.NET with the AdoJob scheduler, so they will be in a database, and on the same server as the database I would have a Windows Service which could read the scheduled jobs and execute them. How should I do this in Quartz.NET? Or is this not the best approach for my problem?
Update: Here's what I'm trying.
Schedule a task from the app using the type name of the class which should be executed
I tried with Quartz.NET to schedule a job using the name and namespace of the class, but it doesn't work, instead of using a direct reference to it. If this would have worked, the next step would've been to start the windows service and see if I could run the job from there.
IJobDetail job = JobBuilder.Create(Type.GetType("SomeNamespace.IHelloJob"))
.WithIdentity("myJobRemote", "remote")
.StoreDurably()
.Build();
The exception message says "Job class cannot be null."
If I make the first step work, then I'll start the windows service and try to run the job inside of it
I use Quartz.net in website for run job forever, and i want run job Automatically in server in every 15 min.
My problem is, User must visit site until application start in global.asax run and it works when user is in site, I want run job without visiting site and start it for ever without users be in site
I am using this code for running job in global.asax
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
SchedulerDemo.Interfaces.ISchedule myTask = new SchedulerDemo.Jobs.HelloSchedule();
myTask.Run();
}
By default in Quartz.net, the jobs list and their trigger will be stored in memory, so as you have suspected, it will have to be defined in the Application_Start to be called on the first request.
You first need to get and start the scheduler in itself.
IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
scheduler.Start();
Then, still in your Application_Start method, you will have to define the job and it's trigger :
// Instantiating the job
IJobDetail jobDetail = JobBuilder.Create<MyJob>()
.WithIdentity(new JobKey("MyVeryImportantJob", "VeryImportantJobGroup"))
.Build();
ITrigger jobTrigger = TriggerBuilder.Create()
.WithIdentity(new TriggerKey("MyVeryImportantJobTrigger", "VeryImportantJobTriggerGroup"))
.WithCronSchedule("* 0/15 * * * ?"") // execute every 15 min (in reality at HH:00, HH:15, HH:30 and HH:45)
.Build();
And join the two to schedule the job
scheduler.ScheduleJob(jobDetail, jobTrigger);
The scheduler will then manage to call your job according to the trigger you defined (in this case, every 15 min).
Also, as Quartz.Net will spawn a dedicated thread for the scheduler, it won't impact iis response process and it will prevent the iis worker to be recycled, so once it's launched, it will run forever until either the iis website or the host server is restarted.
After that, if you REALLY want your scheduler to start with the website without any request at all, you can use the Service Auto Start Provider (more info here :
https://www.simple-talk.com/blogs/2013/03/05/speeding-up-your-application-with-the-iis-auto-start-feature/
)
I need some guidance on creating and running a Cron Job in asp.net(C#.net) to run every 30 minutes.i have created a class in that i have written code for getting tweets, facebook feeds.
i have created another page in that i have one button to download tweets and save in database.
If i want to get tweets i have to click on sync button every time.
i want to create cron job so that the database will get automatically synchronized with new tweets,facebook feeds.
Thanks
You can follow any one of the following approaches
Create a console app with the logic to fetch the tweets and feeds, and use a Task scheduler to run it for every 30 mins.
You could build a windows service, which polls the feeds within a timer and updates the db.
You could checkout this scheduler which is a rough equivalent to cron jobs. Personally haven't tried it. Check out this SO
If your intended 30-minute scheduled task is meant to be a discrete transactional action (like, for instance, your example of synchronizing some database values), then you may want to take a look at the Revalee open source project.
You can use it to schedule web callbacks at specific times. In your case, you could schedule a web callback (30 minutes in the future). When your ASP.NET application receives the callback, it can schedule the next 30 minute callback as well as perform whatever tasks you need it to handle every half-hour. When your ASP.NET application launches for the very first time, then you would schedule the first web callback. Since your web application is being called back, you do not need to worry about your web application unloading (which it will do periodically on IIS, for example).
For example using Revalee, you might do the following:
Register a future (30 minutes from now) callback when your application launches via the ScheduleThirtyMinuteCallback() method (see below).
private DateTimeOffet? previousCallbackTime = null;
private void ScheduleThirtyMinuteCallback()
{
// Schedule your callback 30 minutes from now
DateTimeOffset callbackTime = DateTimeOffset.Now.AddMinutes(30.0);
// Your web service's Uri, including any query string parameters your app might need
Uri callbackUrl = new Uri("http://yourwebapp.com/Callback.aspx");
// Register the callback request with the Revalee service
RevaleeRegistrar.ScheduleCallback(callbackTime, callbackUrl);
previousCallbackTime = callbackTime;
}
When the web scheduled task activates and calls your application back, you perform whatever action you need to do every 30 minutes and you schedule the next callback too. You do this by adding the following method call (CallbackMonitor()) to your Callback.aspx page handler.
private void CallbackMonitor()
{
if (!previousCallbackTime.HasValue
|| previousCallbackTime.Value <= DateTimeOffset.Now.AddMinutes(-30.0))
{
// Perform your "30 minutes have elapsed"-related tasks
// ...do your work here...
// Schedule subsequent 30 minute callback
ScheduleThirtyMinuteCallback();
}
}
To be clear, the Revalee Service is not an external 3rd party online scheduler service, but instead a Windows Service that you install and fully control on your own network. It resides and runs on a server of your own choosing, most likely your web server (but this is not a requirement), where it can receive callback registration requests from your ASP.NET application.
If, however, your 'run every 30 minutes' task is a long running task, then you probably do not want to embed that functionality within your ASP.NET application.
I hope this helps.
Disclaimer: I was one of the developers involved with the Revalee project. To be clear, however, Revalee is free, open source software. The source code is available on GitHub.
I've created the following:
A windows service
A quartz scheduler class
A single IJob implementation called Worker, which contains a set of tasks that I intend to execute via the Quartz scheduler.
The windows service overrides OnStart to call the scheduling/setup class, which attempts to create a single scheduled task within Quartz that I want to run at a given time frame (At the moment, this is simply once per 30 seconds for example, to test the process)
I've used identical code to one of the samples for creating a job and trigger - the trigger containing a chain of code to start immediately and repeat every 30 seconds, forever.
I then call Schedule() and eventually call Start() on the scheduler object.
I use installutil.exe to shove the Service into the services list, I start the service and see my internal logging framework showing me that the service is starting, the scheduler is being created and the job scheduled (logging output line by line since I've been having issues...) The problem is that the task doesn't run once and doesn't ever repeat. The service sits there running happily, but never spins up to execute anything.
If I use the Exists method, passing in the JobKey - it always says false. The count of Jobs is zero, both tested immediately after scheduling and starting the scheduler.
I am setting up the IJobDetail using this approach:
IJobDetail job = JobBuilder.Create<Worker>()
.WithIdentity("job1", "group1")
.Build();
and creating the Trigger with:
TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.ForJob(job)
.StartAt(DateTime.Now)
.WithSimpleSchedule(x => x.WithIntervalInSeconds(30).WithRepeatCount(10))
.Build();
and then to hook it up:
sched.ScheduleJob(job, trigger);
sched.Start();
I am at a loss as to why this is happening, there is nothing in the event log and nothing wrong with the service and the code appears to run through without any problems as I've shoved logging statements (output to txtfile within /bin/debug) after every line & there's plenty of exception handling.
Any ideas? Is the Build() on the generic Create going to tell the scheduler that the type I've defined is where the Execute() method resides?
Edit
Configuration sections I nabbed from this post on SO (#jadenedge's answer) and placed within app.config for the Windows Service. Possibility here of 1.0/2.0 mismatch?
I want the configuration within app.config, ideally, and have no other configuration elsewhere.
Are you starting a thread that keeps the process running? After the service is started, is your process still in memory?
I had this problem and oh boy it drove me absolutely crazy. As it happened I had a spike project that I could always get to run, but my main projects would not run!
The problem: The namespace of my project had dots/periods in it e.g.MyProject.UpdateService where as my spike was simply named QuartzTest.
Debugging through line by line found that when I set my Windows service name to MyProjectUpdateService the Quartz job then registered.
TL/DR:
Ensure your Windows service doesn't have dots in the name.
Update: I've done some more testing and it looks like the maximum length of the service name for a Windows service running Quartz is 25 characters. It doesn't error - it just won't start.
I have created a windows service project in VS and in it I configure Quartz.Net to run a task immediately. The code that registers the task runs with no exception, but the task is never executed as far as my debugging can tell.
I can't be sure because debugging a Windows Service is very different. The way I do it is to programatically launching the debugger from my code. Quartz.Net runs jobs on a separate threads, but I'm not sure if VS2010 can see other running threads when debugging a Windows Service.
Has anyone done what I'm trying before? Any tips are appreciated.
PS. I don't want to use Quartz.Net's own Service.
One of the most common reasons a job doesn't execute, is because you need to call the Start() method on the scheduler instance.
http://quartznet.sourceforge.net/faq.html#whytriggerisntfiring
But it's hard to say what the problem is if we don't have some sort of snippet of the code that does the scheduler creation and job registration.
I see that this is a bit dated, but it came up many times in various searches!
Definitely check out this article, which uses an XML config when the scheduler is instantiated.
http://miscellaneousrecipesfordotnet.blogspot.com/2012/09/quick-sample-to-schedule-tasks-using.html
In case you would rather not use XML (dynamically created tasks and such), replace the "Run" procedure from the article above with something like this:
public void Run()
{
// construct a scheduler factory
ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
_scheduler = schedulerFactory.GetScheduler();
IJobDetail job = JobBuilder.Create<TaskOne>()
.WithIdentity("TaskOne", "TaskOneGroup")
.Build();
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("TaskOne", "TaskOneGroup")
.StartNow()
.WithSimpleSchedule(x => x.WithIntervalInSeconds(20).RepeatForever())
.Build();
_scheduler.ScheduleJob(job, trigger);
_scheduler.TriggerJob(job.Key);
_scheduler.Start();
}
Note - Using Quartz .NET 2.1.2, .NET 4
Cheers!
I have successfully used Quart.NET before in a Windows service. When the service starts-up I create the Scheduler Factory and then get the Scheduler. I then start the scheduler which implicitly reads in the configuration XML I have specified in the App.config of the service.
Quartz.NET basic setup: http://quartznet.sourceforge.net/tutorial/lesson_1.html
App.config Setup Question: http://groups.google.com/group/quartznet/browse_thread/thread/abbfbc1b65e20d63/b1c55cf5dabd3acd?lnk=gst&q=%3Cquartz%3E#b1c55cf5dabd3acd