System.Data.SQLite异步加载问题

时间:2011-07-01 11:32:30

标签: c# linq sqlite asynchronous

我正在使用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方法的整个代码周围放置一个静态锁,问题也解决了。似乎不能同时启动查询,但这可能是真的吗?

2 个答案:

答案 0 :(得分:2)

我发现SQLite数据上下文不是线程安全的。由于linq-queries隐含地使用相同的上下文,我遇到了问题。使用几个上下文摆脱了问题,但不幸的是上下文有单独的缓存(或者看起来如此)所以后台加载我做一个线程将不利于后一个搜索另一个线程。这基本上是整个想法。 如果您当前没有在主线程中访问数据库,则在后台加载仍然很有用。虽然我还没有找到一种优雅的方法来确定它。

答案 1 :(得分:-2)

确定在阅读器关闭之前尝试Thread.Sleep(); p 我认为你的第二个线程需要很长时间才能完成?... 因此,如果在加载其余数据之前关闭连接,那么它的工作方式是什么? 您可能会执行if(thread2 completed)然后完成主线程... else等待; p

我有点混乱了XD ......

我不确定这是不是你的问题......对不起,如果这没有帮助......我喜欢5个月 编程经验:P