1

我已經得到一箇舊的WinForms應用程序來更新和改進。我正在嘗試使用SimpleInjector添加DI。我習慣於.NET MVC,但這是我第一次使用WinForms。使用簡單的噴油器與WinForms中的後臺工作器一起使用EF6保存到數據庫

該應用程序使用了大量的BackGround工作人員。我的理解是,這是特定於WinForms和每個後臺工作人員創建一個新的線程。

我想我的問題是,當我想使用EF6將數據保存到數據庫時,SaveChanges方法由於多個線程而無法保存。

我SimpleInjector容器設置如下

_container = new Container(); 
_container.Options.DefaultScopedLifestyle = new ThreadScopedLifestyle(); 

// Register DbContext 
_container.Register<DbContext, MyDbContext>(Lifestyle.Scoped); 

當我呼籲我的DbContext的SaveChanges我得到0的結果,這表明沒有記錄被保存到數據庫中。在我的調試器中,我得到一個錯誤,說DbContext已經被處置。如果在保存之前發生這種情況,它解釋了爲什麼從SaveChanges返回0。不幸的是,之前的開發人員發現了每個異常,因此應用程序正在嘗試處理每個錯誤,這使得疑難解答變得困難並導致意外行爲。

我期待爲每個線程創建一個新的DbContext,並且SaveChanges將保存在每個線程中所做的更改,以便在一個上下文中發生的操作不會影響其他線程中的其他DbContext。

當我從數據庫中讀取數據時,我在每種方法中手動創建一個新的DbContext。是否有可能,當使用塊已完成它正在處置DbContext?

using (var newDbContext = new MyDbContext()) 
{ 
    return newDbContext.Set<TableA>().First(x => x.Id == id); 
} 

我希望如果我有SimpleInjector配置正確,我也不需要這樣做。

我在這個階段有點迷路,認爲我可能沒有正確理解文檔,任何意見將不勝感激。提前致謝。

回答

2

我期待一個新的DbContext爲每個線程

創建這並不是多麼TheadScopedLifestyle作品。使用ThreadScopedLifestyle,在明確啓動的Scope的上下文中將會有一個註冊實例,並且此作用域是特定於線程的。這意味着一個線程可以擁有該服務的多個實例,因爲一個線程可以長時間存活,而一個線程通常只能存活很短的時間。

的一個典型應用爲ThreadScopedLifestyle如下:

void MethodThatRunsInABackGroundThread() 
{ 
    using (ThreadScopedLifestyle.BeginScope(container)) 
    { 
     var service = container.GetInstance<ISomeService>(); 
     service.DoWork(); 
    } 
} 

當您解決活動範圍之外Scoped實例(或包含範圍的情況下,一些對象圖),簡單的噴油器會拋出異常。

+0

好吧我想我明白,當我引導我的容器時,我不應該指定默認的生活方式是ThreadScope。我可以將其作爲默認範圍,並使用與數據庫通信的類的單例。在我的線程中,我應該指定範圍並將一個新容器傳遞給BeginScope? –

相關問題