如何处理这个(db)队列竞争条件?

时间:2010-01-22 00:24:49

标签: c# multithreading sqlite

基本上我有多线程通过SQLite将数据添加到队列中。我有另一个线程拉动它们并一次处理一个(太多资源一次做多个)。处理线程执行此操作:

  1. 从数据库中提取数据
  2. foreach {proccess}
  3. if count == 0 {thread.suspend()}(由thread.resume()唤醒)
  4. 重复
  5. 我的工作线程确实:

    1. 验证数据
    2. 插入数据库
    3. 调用Queue.Poke(QueueName)
    4. 当我戳它时,如果线程被暂停,我.resume()

      我担心的是,如果进程线程看到count==0,我的工作者会插入并调用,然后我的进程继续执行if和sleep。它不会意识到数据库中有新的东西。

      我应该怎样写这个,以免我遇到竞争条件。

2 个答案:

答案 0 :(得分:1)

处理线程:

  1. event.Reset
  2. 从数据库中提取数据
  3. foreach {proccess}
  4. if count == 0 then event.Wait
  5. 重复
  6. 另一个主题是:

    1. 验证数据
    2. 插入数据库
    3. event.Set()
    4. 你会有额外的醒来(在一个空的队列中醒来,没有什么可以处理,回去睡觉)但你不会错过插入。

答案 1 :(得分:0)

我认为这可能是你需要的结构。

private readonly Queue<object> _Queue = new Queue<object>();
private readonly object _Lock = new object();

void FillQueue()
{
    while (true)
    {
        var dbData = new { Found = true, Data = new object() };
        if (dbData.Found)
        {
            lock (_Lock)
            {
                _Queue.Enqueue(dbData.Data);
            }
        } 

        // If you have multiple threads filling the queue you
        // probably want to throttle it a little bit so the thread
        // processing the queue won't be throttled.
        // If 1ms is too long consider using 
        // TimeSpan.FromTicks(1000).

        Thread.Sleep(1);
    }       
}

void ProcessQueue()
{
    object data = null;

    while (true)
    {
        lock (_Lock)
        {
            data = _Queue.Count > 0 ? _Queue.Dequeue() : null;
        }

        if (data == null)
        {
            Thread.Sleep(1);
        }
        else
        {
            // Proccess
        }         
    }        
}