2014-08-28 89 views
0

我正在處理多線程wpf應用程序我得到「AccessViolationException」說法試圖讀取或寫入受保護的內存。這通常表明其他內存已損壞。我的ConnectionOpen()中的 。我的代碼如下 。由於多線程連接到db時wpf中的AccessViolation異常

public class DatabaseServices 
{ 
    static SQLiteConnection connection; 
    static object conLock = new object(); 
    static object conCloseLock = new object(); 

    public static SQLiteDataReader ConnectionOpen(string Query) 
    { 
     lock (conLock) 
     { 


      if (connection != null && connection.State != System.Data.ConnectionState.Open) 
      { 
       connection = new SQLiteConnection("Data Source=Database/abc.sqlite"); 
       connection.Open(); 
      } 
      else if (connection == null) 
      { 
       connection = new SQLiteConnection("Data Source=Database/abc.sqlite"); 
       connection.Open(); 
      } 
      SQLiteCommand mycommand = new SQLiteCommand(Query, connection); 
      SQLiteDataReader sqlite_datareader = mycommand.ExecuteReader(); 


      return sqlite_datareader; 
     } 
    } 

    public static void ConnectionClose() 
    { 
     lock (conCloseLock) 
     { 
      connection.Close(); 
     } 
    } 

} 

我已經使用鎖以及線程安全代碼,但它不工作。爲什麼?

回答

1

SQLiteConnection不是線程安全的。像所有其他數據庫連接一樣,您應該爲每個線程打開一個連接。事實上,即使代碼線程安全的,您的代碼也會有一些不起作用的部分,但這也無濟於事。例如,任何人都可以關閉連接,而其他人只是在查詢。

保持良好的模式。不要在線程間使用數據庫連接。不要編寫自己的連接緩存。打開連接,做好你的工作,然後關閉它。如果您確定需要連接緩存,請查看數據庫的文檔,並瞭解內置機制的工作原理。

1

SQLite不支持多個活動結果集(MARS)

所以你不能用相同的連接服務的多個的DataReader。

連接(並放下鎖)後,您發出一個DataReader。我假設客戶端代碼調用此ConnectionOpen方法兩次(或者試圖)重新使用相同的連接。

爲每個DataReader創建一個連接。

當您使用連接池:當正常關閉

Data Source=c:\mydb.db;Version=3;Pooling=True;Max Pool Size=100; 

連接將被回收/彙集。這將減少創建和打開連接的開銷。

相關問題