2011-06-16 25 views
6

मेरे पास एक विंडोज़ सेवा है और मैं यह सुनिश्चित करना चाहता हूं कि मेरा ईएफ ऑब्जेक्ट कॉन्टेक्स्ट प्रत्येक बार इसके रनों के बीच का निपटारा हो। जब भी यह निष्पादित होता है तो सेवा लंबे समय तक चलती है। ऐसा लगता है जैसे ऑब्जेक्ट कॉन्टेक्स्ट बढ़ता रहता है। क्या मेरा ऑब्जेक्ट कॉन्टेक्स्ट अलग-अलग पंजीकृत होना चाहिए या क्या मैं कुछ गलत कर रहा हूं?क्या मैं ऑटोकैक का उपयोग कर ऑब्जेक्ट कॉन्टेक्स्ट को सही तरीके से पंजीकृत कर रहा हूं?

मैं जो कर रहा हूं उसका एक अवलोकन।

  • मैं Quartz.NET उपयोग कर रहा हूँ मेरी सेवा
  • शेड्यूल करने के लिए मैं कॉन्फ़िगर करने के लिए और सेटअप मेरी खिड़कियों सेवा
  • मेरी आईओसी
  • मैं उपयोग कर रहा हूँ इकाई की रूपरेखा के रूप में मैं Autofac उपयोग कर रहा हूँ Atlas उपयोग कर रहा हूँ

      : मेरे डेटा मॉडल

    कोड की Walkthru के रूप में

  • तो प्रोग्राम एटलस का उपयोग करके सेवा पंजीकृत करके बंद हो जाता है।
  • एटलस मेरी autofac पंजीकरण जो मॉड्यूल MyModule में रखे जाते हैं रजिस्टर करेंगे
  • MyModule रजिस्टरों InstancePerLifetimeScope पर ObjectContext (यह सही गुंजाइश है?), तो यह एक InstancePerLifetimeScope के रूप में अपने कस्टम UnitOfWork का उदाहरण एक बार होगा (क्या यह सही दायरा?)।
  • माईस सर्विस एटलस द्वारा होस्ट किया जाता है जो क्वार्ट्ज शेड्यूलर और ऑटोफैक जॉब लिस्टनर संपत्ति इंजेक्शन प्राप्त करता है और सेवा शुरू होने पर हर 5 मिनट चलाने के लिए नौकरी (MyJob) शेड्यूल करता है।
  • MyJob जो AutocacJobListener से ऑब्जेक्ट कॉन्टेक्स्ट प्रॉपर्टी का उदाहरण प्राप्त करता है। यह नौकरी डेटाबेस में कॉल करती है और मुझे मेरी सामग्री मिलती है।

जब नौकरी चलती है तो यह कॉल करता है और जब भी यह चलता है तो मेरी सामग्री हर बार ले जाती है (उदाहरण: पहली बार यह 2 मिनट चलता है, दूसरी बार सेवा चलने में 4 मिनट, अगले 6 मिनट, 8 अगले और इतने पर)। ऐसा लगता है कि मेरे ऑब्जेक्ट कॉन्टेक्स्ट हर बार बड़ा और बड़ा हो रहा है। डेटा खींचने वाला डेटा नहीं बदला है, फिर भी पंक्तियों और स्तंभों की एक ही संख्या है। तो मैं सोच रहा हूं कि मेरे पंजीकरण गलत हैं, क्या यह मामला है? यदि आप नहीं कर रहे हैं तो क्या आप एक समस्या देख सकते हैं?

कार्यक्रम

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>(); 
    } 
} 

उत्तर

6

आप इसे सही ढंग से दर्ज कर रहे हैं, लेकिन आप एक जीवन भर के दायरे के भीतर इसे प्रयोग नहीं कर रहे हैं तो यह की वजह से तकनीकी रूप से अपने lifetimescope है निपटारा नहीं की जाएगी आवेदन का जीवन

एटलस सबकुछ पंजीकृत करता है और एप्लिकेशन के जीवनकाल में चलता है, इसलिए यदि आप जीवनकाल के निर्माण के बिना केवल उदाहरणों को हल करते हैं, तो उन्हें एप्लिकेशन के जीवनकाल के दायरे के लिए हल किया जाता है। विंडोज अनुप्रयोगों में लाइफटाइमस्कोप आपके लिए पूर्व निर्धारित नहीं है क्योंकि यह वेब अनुप्रयोगों में है, आपको इसे परिभाषित करना होगा। आपके मामले में आपको एक ही नौकरी के निष्पादन के आसपास एक लाइफटाइमस्कोप बनाना होगा।

निष्पादित पर निष्पादन और निपटान पर AutofacJobListener में LifetimeScope बनाएं। यह उस दायरे में हल किए गए सभी उदाहरणों के जीवनकाल को मजबूर करेगा, यानी आपके ObjectContext, केवल उस दायरे की अवधि के लिए, नौकरी के निष्पादन के लिए मौजूद है।

तरह

_lifetimeScope = container.BeginLifetimeScope(); 
_lifetimeScope.InjectUnsetProperties(context.JobInstance); 

और

_lifetimeScope.Dispose();
उचित तरीकों में

कुछ जोड़ें।

+0

धन्यवाद बिल्कुल वही है जो मैं देख रहा था और मैं वास्तव में एक कदम आगे चला गया और एटलस की शक्ति का उपयोग किया। मैंने अपने AutofacJobListener को एटलस में प्रवेश करने के लिए बदल दिया। कंटेनरप्रोवाइडर। इसके बाद कंटेनरप्रोवाइडर की BeginLifetimeScope() – Mark

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^