我有一个Windows服务,我想确保我的EF ObjectContext在每次运行之间被处理掉。每次执行时,服务运行的时间都会更长。似乎ObjectContext不断增长。我的ObjectContext应该注册不同还是我做错了什么?
我正在做的事情的概述。
代码的Walkthru:
当作业运行时,它会在每次运行时调用并获取我的东西需要更长时间(例如:第一次运行时为2分钟,第二次运行服务时为4分钟,下一次为6分钟,下一次为8分钟,等等)。看起来我的ObjectContext每次都变得越来越大。它拉动的数据没有改变,行数和列数仍然相同。所以我认为我的注册错了,是这样的吗?如果没有,你能看到我正在做的事情的问题吗?
程序
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
var configuration =
Host.Configure<MyService>(c =>
{
c.AllowMultipleInstances();
c.WithRegistrations(b => b.RegisterModule(new MyModule()));
}, args);
Host.Start(configuration);
}
}
模块
public class MyModule : Module
{
protected override void Load(ContainerBuilder builder)
{
LoadQuartz(builder);
LoadServices(builder);
LoadInfrastructure(builder);
}
private void LoadInfrastructure(ContainerBuilder builder)
{
builder.Register(c => new ObjectContext())
.As<IObjectContext>()
.InstancePerLifetimeScope();
builder.Register(c => new UnitOfWork(c.Resolve<IObjectContext>()))
.As<ISession>().As<IObjectContextProvider>()
.InstancePerLifetimeScope();
}
private void LoadQuartz(ContainerBuilder builder)
{
builder.Register(c => new StdSchedulerFactory().GetScheduler()).As<IScheduler>().InstancePerLifetimeScope();
builder.Register(c => new AutofacJobListener(c)).As<IJobListener>();
}
private void LoadServices(ContainerBuilder builder)
{
builder.RegisterType<MyService>().As<IAmAHostedProcess>().PropertiesAutowired();
}
}
AutofacJobListener
public class AutofacJobListener : IJobListener
{
private readonly IComponentContext _container;
public AutofacJobListener(IComponentContext container)
{
_container = container;
}
public void JobToBeExecuted(JobExecutionContext context)
{
_container.InjectUnsetProperties(context.JobInstance);
}
public void JobExecutionVetoed(JobExecutionContext context)
{
/*noop*/
}
public void JobWasExecuted(JobExecutionContext context, JobExecutionException jobException)
{
/*noop*/
}
public string Name
{
get { return "AutofacInjectionJobListener"; }
}
}
为MyService
public class MyService : IAmAHostedProcess
{
public IScheduler Scheduler { get; set; }
public IJobListener AutofacJobListener { get; set; }
#region Implementation of IAmAHostedProcess
public void Start()
{
var trigger = TriggerUtils.MakeMinutelyTrigger(5);
trigger.Name = @"Job Trigger";
Scheduler.ScheduleJob(new JobDetail("Job", null, typeof(MyJob)), trigger);
Scheduler.AddGlobalJobListener(AutofacJobListener);
Scheduler.Start();
}
public void Stop()
{
Scheduler.Shutdown();
}
public void Resume()
{
}
public void Pause()
{
}
#endregion
}
我的工作
public class MyJob : IJob
{
public IObjectContext ObjectContext { get; set; }
public void Execute(JobExecutionContext context)
{
var myStuff = ObjectContext.GetIQueryable<Stuff>();
}
}
答案 0 :(得分:6)
您正在正确注册,但您并未在生命周期范围内使用它,因此不会将其丢弃,因为从技术上讲,您的生命时间镜就是应用程序的生命周期。
Atlas注册所有内容并在应用程序的lifetimescope中运行,因此如果您只解析实例而不创建生命周期镜,则可以解决它们在应用程序生命周期范围内的问题。在Windows应用程序中,生命周期镜不像Web应用程序那样为您预先确定,您必须对其进行定义。在您的情况下,您需要创建一个围绕单个作业执行的生命周期。
在执行中的LifetimeScope
中创建AutofacJobListener
并在执行时将其丢弃。这将强制在该范围内解析的所有实例(即ObjectContext
)的生命周期仅在该范围的持续时间内存在,即作业的执行。
添加类似
的内容_lifetimeScope = container.BeginLifetimeScope();
_lifetimeScope.InjectUnsetProperties(context.JobInstance);
和
_lifetimeScope.Dispose();
采用适当的方法。