私はWindowsサービスを使用しており、EFObjectContextが実行されるたびに確実に破棄されるようにしたいと考えています。サービスは、実行するたびに長く実行されます。ObjectContextは成長し続けているようです。ObjectContextを別の方法で登録する必要がありますか、それとも何か間違ったことをしていますか?
私がしていることの概要。
- Quartz.NETを使用してサービスをスケジュールしています
- Atlasを使用してWindowsサービスを構成およびセットアップしています
- IoCとしてAutofacを使用しています
- データモデルとしてEntityFrameworkを使用しています
コードのウォークスルー:
- そのため、プログラムはAtlasを使用してサービスを登録することで開始されます。
- Atlasは、モジュールMyModuleに格納されているautofac登録を登録します
- MyModuleはObjectContextをInstancePerLifetimeScopeに登録し(これは正しいスコープですか?)、カスタムUnitOfWorkのインスタンスをInstancePerLifetimeScopeとして一度持つことになります(これは正しいスコープですか?)。
- MyServiceはAtlasによってホストされ、QuartzスケジューラーとAutofacJobListenerプロパティが注入され、サービスの開始時に5分ごとに実行されるようにジョブ(MyJob)がスケジュールされます。
- AutofacJobListenerからObjectContextプロパティのインスタンスが注入されたMyJob。この仕事はデータベースを呼び出して、私に私のものを手に入れます。
ジョブが実行されると、実行するたびに呼び出して私のものを取得するのに時間がかかります(例:最初の実行で2分、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>();
}
}