我正在使用System.Data.SQLite
使用c#/linq
查询数据库。
我想要显示的行包含来自各种表的数据。我目前所做的是查询一个表以获取我放在DataGrid中的项目的完整列表。由于虚拟化,我可以懒洋洋地查询其他表,因为相关的Row会进入视图。这很好。
现在我想立即开始填充行中缺少的数据,但是异步。但每次我在另一个线程中执行延迟加载代码时,我都会收到“ 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方法的整个代码周围放置一个静态锁,问题也解决了。似乎不能同时启动查询,但这可能是真的吗?
答案 0 :(得分:2)
我发现SQLite数据上下文不是线程安全的。由于linq-queries隐含地使用相同的上下文,我遇到了问题。使用几个上下文摆脱了问题,但不幸的是上下文有单独的缓存(或者看起来如此)所以后台加载我做一个线程将不利于后一个搜索另一个线程。这基本上是整个想法。 如果您当前没有在主线程中访问数据库,则在后台加载仍然很有用。虽然我还没有找到一种优雅的方法来确定它。
答案 1 :(得分:-2)
确定在阅读器关闭之前尝试Thread.Sleep(); p 我认为你的第二个线程需要很长时间才能完成?... 因此,如果在加载其余数据之前关闭连接,那么它的工作方式是什么? 您可能会执行if(thread2 completed)然后完成主线程... else等待; p
我有点混乱了XD ......
我不确定这是不是你的问题......对不起,如果这没有帮助......我喜欢5个月 编程经验:P