2011-07-01 79 views
0

我使用System.Data.SQLitec#/linq查詢數據庫。 我想要顯示的行包含來自各種表格的數據。我目前所做的是查詢一個表以獲取我放置在DataGrid中的項目的完整列表。感謝虛擬化,我可以懶懶地查詢其他表格,因爲相關的行進入視圖。這工作正常。System.Data.SQLite異步加載問題

現在我想開始在行中立即填寫缺失的數據,但是是異步的。但我收到一個異常「DataReader已關閉」,每次我在不同的線程中執行延遲加載代碼。這是否與「原始」linq查詢是從另一個線程完成的事實?

任何想法如何解決這個問題?

下面是一些代碼,希望總結了問題

//Main thread--- 

//Start the search 
_startEvent.Set(); 
_mainLoadEvent.WaitOne(); 
_mainLoadEvent.Reset(); 


//Worker thread--- 

_startEvent.WaitOne(); 
_startEvent.Reset(); 

SearchAllLiterature(); //Fills _searchResults with rows 

_mainLoadEvent.Set(); //Signal to mainthread that all rows are loaded 

//Fill in some details for every row, that come from various sources, we'll need them later 
foreach (var r in _searchResults) 
    r.LazyLoadText(); 


//SearchResultRow.cs 

public string Author 
{ 
    get 
    { 
     LazyLoadText(); 
     return _author; 
    } 

    set 
    { 
     _author = value; 
    } 
} 


//Called by the worker thread or by the DataGrid when a new row comes into view 
public void LazyLoadText() 
{ 
    lock (this) 
    { 
     if (_lazyLoadTextCompleted) return; 

     _lazyLoadTextCompleted = true; 
    } 

    var sb = new StringBuilder(); 

    //this will result in a SQL-query 
    var authors = from a in _source.ReferenceOrganization 
       orderby a.Person.LastName 
       select a.Person; 

    Author = ConcatAuthors(authors, sb); 

    //...more queries... 
} 

提高懶加載環後_mainLoadEvent不顯示了同樣的問題。

如果我在LazyLoad方法的整個代碼中加入靜態鎖,問題也解決了。似乎並行地開始查詢並不好,但這可能是真的嗎?

+2

請張貼一些相關的代碼... – 2011-07-01 11:35:13

+0

我在我的文章中添加了一些代碼。有趣的是,如果在啓動延遲加載之前,工作線程休眠約1秒,問題就會消失。我想這給了UI足夠的時間來完成那些需要顯示的行的延遲加載。但爲什麼這是一個問題?我的鎖機制錯了嗎? –

回答

2

我發現SQLite數據上下文不是線程安全的。作爲隱式使用相同上下文的linq查詢,我遇到了一個問題。使用幾個上下文擺脫了這個問題,但不幸的是,上下文有單獨的緩存(或者看起來像這樣),所以後臺加載我做一個線程不會有利於以後在另一個線程上搜索。基本上是整個想法。 如果您當前未在主線程中訪問數據庫,則在後臺加載仍然很有用。雖然我還沒有真正想出一個優雅的方式來確定這一點。

+0

每個線程的單獨緩存不再是一個問題,已經有一段時間了。此外,3.7.0中引入的預寫式日誌記錄功能使得多線程特別是多進程性能更好。 –

+0

我對處理後臺加載的建議是隻使用一個線程進行加載。讓主線程觸發後臺線程立即開始加載第一條記錄,並在加載後將數據(不是數據讀取器,而是數據,即值對象或數據表)傳回主線程。後臺線程可以繼續在後臺加載。這就是說,根據我的經驗,sqlite的性能足以支持後臺加載。也許你應該增加你的頁面大小和緩存大小。 –

+0

獨立緩存以何種方式不成問題?我可以衡量搜索速度的差異。我只從一個線程加載。但是我也在每一行中都沒有顯示的情況下使用延遲加載。但是它發生了,我仍然在後臺加載,而UI(另一個線程可以這麼說)通過訪問屬性請求延遲加載。這就是問題出現的地方。 –

-2

好的嘗試了Thread.Sleep()閱讀器關閉之前; 2 P 我覺得你的第二個線程正在長來完成吧... 所以,如果你的數據的其餘部分被加載之前您連接關閉它是如何suposse上班? 你可能會做這樣的事情,如果(線程2完成),然後完成主線程...否則等待,P

我prolly搞砸了一下XD ...

我不知道,如果這是你的問題...; p對不起,如果這沒有幫助...我已經5個月了 編程經驗:P

+0

我不是那個關閉閱讀器的人,否則我會等到第二個線程完成它的工作。我想我正在遇到另一個問題。還是你的意思是別的? –