我是Asp.net
的新手,并且使用Entity Framework
建立了一个网站。每天晚上,我都需要在我的Person
实体上做一些工作。
因此我安装了Quartz.Net
et尝试在Global.asax
中使用它{/ p>
<%@ Application Language="C#" %>
<%@ Import Namespace="Quartz" %>
<%@ Import Namespace="Quartz.Impl" %>
<script runat="server">
private IScheduler Scheduler { get; set; }
void Application_Start(object sender, EventArgs e)
{
Scheduler = StdSchedulerFactory.GetDefaultScheduler();
Scheduler.Start();
IJobDetail dailyReset = JobBuilder.Create<ApplicationJobs.DailyReset>()
.WithIdentity("dailyReset", "group1")
.Build();
ITrigger dailyResetTrigger = TriggerBuilder.Create()
.WithIdentity("dailyResetTrigger", "group1")
.StartAt(DateBuilder.DateOf(3, 0, 0))
.WithSimpleSchedule(x => x
.WithIntervalInHours(24)
.RepeatForever())
.Build()
Scheduler.ScheduleJob(dailyReset, dailyResetTrigger);
}
</script>
然后是我的ApplicationJobs类:
public class ApplicationJobs : System.Web.HttpApplication
{
public class DailyReset : IJob
{
public void Execute(IJobExecutionContext context)
{
using (var uow = new UnitOfWork())
{
foreach (Person person in uof.Context.Persons)
{
//do something
}
}
}
}
}
最后是UnitOfWork:
public class UnitOfWork : IDisposable
{
private const string _httpContextKey = "_unitOfWork";
private MyEntities _dbContext;
public static UnitOfWork Current
{
get { return (UnitOfWork)HttpContext.Current.Items[_httpContextKey]; }
}
public UnitOfWork()
{
HttpContext.Current.Items[_httpContextKey] = this;
}
public MyEntities Context
{
get
{
if (_dbContext == null)
_dbContext = new MyEntities();
return _dbContext;
}
}
}
但using (var uow = new UnitOfWork())
因uow的构造函数中的HttpContext.Current.Items[_httpContextKey] = this;
而无效;我读到HttpContext.Current
中没有Application_Start
。
在阅读相关帖子中,特别是this one,但我真的不明白我是否需要创建类似UnitOfWorkScope
described here的内容,或者是否有办法实现就像现在一样。
那么是否有任何干净安全的方法来安排一些使用我的UnitOfWork
来更新实体的任务?
非常感谢。
答案 0 :(得分:2)
你的问题来自这样一个事实:当你的工作运行时,它将由石英计划器调用,而不是来自http请求(即使作业在ASP网站中)。
所以HttpContext.Current很可能是null。
在使用Quartz时请记住,您认为它是一个完全平行的网站流程,几乎就像一个单独的服务。
如果你需要通过&#34;论证&#34;为了您的工作,您可以使用工作数据地图
JobDataMap dataMap = jobContext.JobDetail.JobDataMap;
(有关详情,请参阅此处:http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/more-about-jobs.html)
如果您需要访问作业,只需在创建jobkey时使用相同的键和组(您在 WithIdentity中使用的那个
请注意,建议实体上下文仅在您需要的操作时保持活动状态,因此您可能只需在作业开始时实例化新上下文并在最后处置它。
答案 1 :(得分:1)
问题是您没有在Web请求中执行作业。在Web请求启动时,您检查未完成的工作,如果需要,请执行工作,请求结束。没有Web请求,您就没有上下文 - 因为上下文是Web请求的生命周期,可以通过请求线程访问。
您将要遇到的另一个问题是,如果没有活动,使用默认设置的应用池可能会结束。所以你需要一种方法让它保持活力。
另一种方法是使用win task scheduler之类的东西来点击网站开始工作。