2015-09-10 24 views
0

我有一個封裝的try/catch塊與EF的DbContexts結合的問題。爲DbContext使用塊的例外

我的代碼被認爲是在以下各項:

var hasToBeRepaired = false; 
Exception ex = null; 
try 
{ 
    SqlCeToSqLite(testContext); 
} 
catch(Exception exc) 
{ 
    hasToBeRepaired = true; 
    ex = exc; 
} 
if (hasToBeRepaired) 
{ 
    testContext.Dispose(); 
    GC.Collect(); 
    RepairComplete(_bl.BlShip.Imo, backupLastCe.BackUpPath); 
} 

在SqlCeToSqLite以下使用:

using(var emptydbcontext = new WriteObjectsContext(builder.ToString(), Providers.SqLite)) 
     { 
      .... 
     } 

這基本上是從複製的TestContext表到新的上下文(emptydbcontext)。 當拋出異常時,我想從之前創建的備份中恢復,這是在RepairComplete()函數中完成的。這涉及到首先刪除數據路徑中的所有項目,然後從那裏移動備份中的項目。

但是,當我想刪除由emptydbcontext創建的數據庫時,它會拋出IOException「進程無法訪問文件'9622241.s3db',因爲它正在被另一個進程使用。」

這告訴我上下文仍然是打開的,儘管它應該在使用()塊的時候拋出異常嗎?收集垃圾清理任何被處置的物體並沒有幫助。 RepairComplete不會創建任何上下文,它只是刪除文件(在那裏崩潰),然後移動備份的文件。

爲什麼它不能這樣工作,當離開使用塊+通過GC時不應該處理上下文嗎?我能做些什麼來解決這個問題?

回答

0

好吧,我嘗試了幾件事情。首先我讀了重建使用的Sqlite DLL,因爲它似乎是一個EF + Sqlite相關的問題,建議in this post

但是,使用更新的源代碼仍然無法正常工作。現在我懷疑它是在處理上下文並且錯誤處理結束之後調用GC的,我認爲即使在處理上下文以供參考之後,EF仍然存儲它的命令。

現在我去了錯誤處理權在發生錯誤的功能(在使用塊)是這樣的:

using(var emptydbcontext = new WriteObjectsContext(builder.ToString(), Providers.SqLite)) 
    { 
     try 
     { 
      .... 
     } 
     catch(Exception) 
     { 
      GC.SuppressFinalize(emptydbcontext); 
      emptydbcontext.Dispose(); 
      GC.Collect(); 
      throw; 
     } 
    } 

隨着呼叫suppressFinalize不處置已佈置背景下使用時,塊結束了(雖然它對我來說從來都不是問題),但它現在起作用了。當然,它只是調用GC.Collect(),本身並不可靠,所以我想有一個更好的選擇,但至少它現在適用於某些。