Quartz.net setup in an asp.net website
Did you try the quartz.net tutorial?
Since your web app might get recycled/restarted, you should probably (re-)intialize the quartz.net scheduler in the Application_Start handler in global.asax.cs.
Update (with complete example and some other considerations):
Here's a complete example how to do this using quartz.net. First of all, you have to create a class which implements the IJob
interface defined by quartz.net. This class is called by the quartz.net scheduler at tne configured time and should therefore contain your send mail functionality:
using Quartz;
public class SendMailJob : IJob
{
public void Execute(JobExecutionContext context)
{
SendMail();
}
private void SendMail()
{
// put your send mail logic here
}
}
Next you have to initialize the quartz.net scheduler to invoke your job once a day at 06:00. This can be done in Application_Start
of global.asax
:
using Quartz;
using Quartz.Impl;
public class Global : System.Web.HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
ISchedulerFactory schedFact = new StdSchedulerFactory();
// get a scheduler
IScheduler sched = schedFact.GetScheduler();
sched.Start();
// construct job info
JobDetail jobDetail = new JobDetail("mySendMailJob", typeof(SendMailJob));
// fire every day at 06:00
Trigger trigger = TriggerUtils.MakeDailyTrigger(06, 00);
trigger.Name = "mySendMailTrigger";
// schedule the job for execution
sched.ScheduleJob(jobDetail, trigger);
}
...
}
That's it. Your job should be executed every day at 06:00. For testing, you can create a trigger which fires every minute (for example). Have a look at the method of TriggerUtils
.
While the above solution might work for you, there is one thing you should consider: your web app will get recycled/stopped if there is no activity for some time (i.e. no active users). This means that your send mail function might not be executed (only if there was some activity around the time when the mail should be sent).
Therefore you should think about other solutions for your problem:
- you might want to implement a windows service to send your emails (the windows service will always be running)
- or much easier: implement your send mail functionality in a small console application, and set up a scheduled task in windows to invoke your console app once a day at the required time.
Using Quartz.Net in asp.net application
I think the answer here might help.
You can have a look at Example12 in Quartz.2008 project.
Your configuration file must be like this:
<!-- Configure Thread Pool -->
<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
<add key="quartz.threadPool.threadCount" value="5" />
<add key="quartz.threadPool.threadPriority" value="Normal" />
<!--Configure remoting expoter-->
<add key="quartz.scheduler.proxy" value="true" />
<add key="quartz.scheduler.proxy.address" value="tcp://localhost:555/QuartzScheduler" />
One thing to remember: you'll never start the scheduler.
Since you're hosting Quartz.net in ASP.NET you have to define your scheduler as singleton.
How to use Quartz.net with ASP.NET
You have a couple of options, depending on what you want to do and how you want to set it up. For example, you can install a Quartz.Net server as a standalone windows serviceor you can also embed it inside your asp.net application.
If you want to run it embedded, then you can start the server from say your global.asax, like this (from the source code examples, example #12):
NameValueCollection properties = new NameValueCollection();
properties["quartz.scheduler.instanceName"] = "RemoteServer";
// set thread pool info
properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
properties["quartz.threadPool.threadCount"] = "5";
properties["quartz.threadPool.threadPriority"] = "Normal";
ISchedulerFactory sf = new StdSchedulerFactory(properties);
IScheduler sched = sf.GetScheduler();
sched.Start();
If you run it as a service, you would connect remotely to it like this (from example #12):
NameValueCollection properties = new NameValueCollection();
properties["quartz.scheduler.instanceName"] = "RemoteClient";
// set thread pool info
properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
properties["quartz.threadPool.threadCount"] = "5";
properties["quartz.threadPool.threadPriority"] = "Normal";
// set remoting expoter
properties["quartz.scheduler.proxy"] = "true";
properties["quartz.scheduler.proxy.address"] = "tcp://localhost:555/QuartzScheduler";
// First we must get a reference to a scheduler
ISchedulerFactory sf = new StdSchedulerFactory(properties);
IScheduler sched = sf.GetScheduler();
Once you have a reference to the scheduler (be it via remoting or because you have an embedded instance) you can schedule jobs like this:
// define the job and ask it to run
JobDetail job = new JobDetail("remotelyAddedJob", "default", typeof(SimpleJob));
JobDataMap map = new JobDataMap();
map.Put("msg", "Your remotely added job has executed!");
job.JobDataMap = map;
CronTrigger trigger = new CronTrigger("remotelyAddedTrigger", "default", "remotelyAddedJob", "default", DateTime.UtcNow, null, "/5 * * ? * *");
// schedule the job
sched.ScheduleJob(job, trigger);
Here's a link to some posts I wrote for people getting started with Quartz.Net:
http://jvilalta.blogspot.com/2009/03/getting-started-with-quartznet-part-1.html
How to use Quartz.NET with ASP.NET Core Web Application?
You may use ConfigureServices
or Configure
methods.
Although Configure
method is mainly used to configure the HTTP request pipeline, the benefit is that you directly can use IHostingEnvironment
(and so get configuration settings) and ILoggerFactory
interfaces. And using ConfigureServices
method those dependencies may be accessed if you create corresponding properties in Startup
class.
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
Quartz.NET from config.xml in ASP.NET
Your job type needs to be specified as
<job-type>Fully.Qualified.Type.Name, AssemblyNameWithoutTheDllExtension</job-type>
Quartz.Net in ASP.Net Application
as you said, scheduler should be a singleton. with the code about scheduler is not a singleton and the scheduler only exists in the scope of the application starting, not the application running.
public static IScheduler Scheduler { get; private set; }
private void StartScheduler()
{
Scheduler = new StdSchedulerFactory().GetScheduler();
Scheduler.Start();
var jobDetail = JobBuilder
.Create()
.OfType(typeof(DBCleanUpJob))
.WithIdentity(new JobKey("test", "1"))
.Build();
var trigger = Quartz.TriggerBuilder.Create()
.ForJob(jobDetail)
.WithIdentity(new TriggerKey("test", "1"))
.WithSimpleSchedule()
.StartNow()
.Build();
//.WithDailyTimeIntervalSchedule(x=>x.StartingDailyAt(new TimeOfDay(09,00)));
Scheduler.ScheduleJob(jobDetail, trigger);
}
and as Jehof pointed out. IIS will shutdown a website/application if there is no activity for a certain period of time.
Also note that your jobs will not have access to the asp.net pipeline. the jobs do not execute within the context of a request, therefore session, request, response, cookies are not available to the job.
Finally, if you want the scheduler to always run it will need to be independent of the website. Windows services are a good candidate. create a windows service project and have the scheduler start when the service starts. you could then setup quartz on the website to proxy jobs to the windows service. allowing the site to schedule jobs but the actual storage and execution is performed by the windows service scheduler.
Related Topics
How to Cast Expression<Func<T, Datetime>> to Expression<Func<T, Object>>
How to Have a Loop in a Windows Service Without Using the Timer
Difference Between the Keydown Event, Keypress Event and Keyup Event in Visual Studio
Webdriver How to Wait Until the Element Is Clickable in Webdriver C#
How to Get Text Between Nested Parentheses
Can Someone Explain How Bcrypt Verifies a Hash
How to Get All Cookies of a Cookiecontainer
How Should You Diagnose the Error Sehexception - External Component Has Thrown an Exception
What Do the "+N" Values Mean at the End of a Method Name in a Stack Trace
How to Print PDF on Default Network Printer Using Ghostscript (Gswin32C.Exe) Shell Command
Why Won't Anyone Accept Public Fields in C#
Read from a File Starting at the End, Similar to Tail
Getting the Index of a Particular Item in Array
Encoding Xpath Expressions with Both Single and Double Quotes
How to Get Current User Who's Accessing an ASP.NET Application