1

我正在寫一個任務執行引擎,我遇到了一些問題,關於什麼是適當的方法來確保當我在任務執行環境中使用Castle.Windsor(ver 2.5.1.0)時, Parallels-Library系統。在使用Castle.Windsor和Task Parallels Library的Windows服務中,什麼是適當的生活方式和發佈過程?

我已經包括了一個高度簡化的僞代碼示例,我在帖子結尾處做了些什麼。

這裏是我的問題

  • Castle.Windsor沒有一個「PerTask」的生活方式,並給予TPL使用線程的方式,我相信PerThread生活方式將無法正常工作。那麼什麼是適當的生活方式?
  • 如果我強制TPL成爲Task-Per-Thread機制,那麼我的理解是,調用PerThread生活方式的Release將不會實際釋放任何東西,直到容器被處置掉,目前我只有一個容器永遠。有沒有更好的方法來設置我的容器來支持PerThread?
  • 在下面的示例中,我還指出了三個可以在容器上調用釋放的潛在位置。根據我讀過的大部分內容,我應該很少需要自己致電發佈,但如果我不在這些地方打電話,那麼這些註冊如何處置?

的服務:

class Service : ServiceBase 
{ 
    IWindsorContainer _container; 
    Engine _engine; 

    public Service() 
    { 
     _container = new WindsorContainer(); 
     _container.Register(Component.For<Engine>().ImplementedBy<Engine>().LifeStyle.Singleton); 
     _container.Register(Component.For<ISession>().UsingFactoryMethod(() => SessionFactory.Get()); 
     _container.Register(Component.For<IDataAccess>().ImplementedBy<SqlDataAccess>()); 
     _container.Register(Component.For<IWorker>().ImplementedBy<DocumentWorker>()); 
     _container.Register(Component.For<IDependency>().ImplementedBy<SomeDependency>()); 
    } 

    protected override void OnStart(string[] args) 
    { 
     _engine = _container.Resolve<Engine>(); 
     _engine.Start(); 
    } 

    protected override void OnStop() 
    { 
     _container.Release(_engine); //1? 
    } 
} 

「引擎」:

class Engine 
{ 
    IWindsorContainer _container 
    public Engine(IWindsorContainer container) 
    { 
     _container = container; 
    } 

    public void Start() 
    { 
     Task.Factory.StartNew(() => Work()); 
    } 

    public void Work() 
    { 
     var worker = _container.Resolve<IWorker>(); 
     worker.DoWork(); 
     _container.Release(worker); //2? 
    } 
} 

工人任務:

class Worker : IWorker 
{ 
    IDataAccess _accessor; 
    IWindsorContainer _container; 
    public Worker(IDataAccess accessor, IWindsorContainer container) 
    { 
     _accessor = accessor; 
     _container = container; 
    } 

    public void DoWork() 
    { 
     var depen = _container.Resolve<IDependency>(); 
     //DoWork 
     _container.Release(depen); //3? 
    } 
} 

謝謝,我會很高興,如果進一步闡述需要更多細節。

+0

如何註冊組件瞬態?然後,每次調用組件的解析時,都會收到一個新實例。 – Simon

+0

主要是因爲,雖然這個例子並沒有完全顯示出來,但我並不想讓所有的東西都是瞬態的。但這是一個可能的解決方案。 – Dugan

+1

似乎是http://stackoverflow.com/questions/5226659/castle-custome-lifestyle-per-resolve和http://stackoverflow.com/questions/3986747/how-to-reuse-a-transient - 依賴於同一上下文 - 與城堡 - windsor-di-conta –

回答

2

我知道在大多數情況下,溫莎城堡建議每個應用程序域包含1個Conatiner,但是您可以擁有儘可能多的數量。有IOC設計模式使用多個容器,例如每個DLL一個容器。在這個senario中,您可能需要每個線程或進程一個容器,以及其他應用程序的一個容器。希望這會有所幫助

+0

因此,我創建並銷燬一個容器,每次創建/銷燬一個任務時,他們都會如此? – Dugan

+0

是的,這將釋放垃圾回收資源。你會希望在任務本身內創建和銷燬容器。這將開始新鮮和結束清潔隔離。 – Darren

0

我的經驗是設置一個容器相當昂貴,這很好,因爲它通常是一次性的體驗。但是,如果我們按照任務完成它,就像這裏提到的那樣,我們失去了性能增益,我們可能希望通過使用任務。

我也在爲此苦苦掙扎。由於大多數組件都是共享的,因此我使用HybridPerWebRequest/Thread生活方式,我不希望實例化程序需要知道較低級別的內部細節,因此它們應該使用我提供給它們的Castle Installers。

我現在遇到的問題也與每個任務創建不被真正支持的事實有關,所以當新生成的任務不使用與主線程相同的線程時,我丟失了一些「StateFull」服務。 城堡會正常工作,因爲它會產生一個新的對象。但在這種情況下,我失去了主線的狀態。

我正在考慮通過刪除任務創建來減少formante。

相關問題