C# 如何处理此(db)队列争用情况?

C# 如何处理此(db)队列争用情况?,c#,multithreading,sqlite,C#,Multithreading,Sqlite,基本上,我有多个线程,通过SQLite将数据添加到队列中。我还有另外一个线程,它一次只处理一个线程(太多的资源无法同时处理多个线程)。处理线程执行以下操作: 从数据库中提取数据 foreach{PROCESS} 如果计数=0{thread.suspend()}(由thread.resume()唤醒) 重复 我的工作线程执行以下操作: 验证数据 插入数据库 call Queue.Poke(队列名称) 当我戳它时,如果线程被挂起,我将.resume()它 我担心的是,如果进程线程看到count==0

基本上,我有多个线程,通过SQLite将数据添加到队列中。我还有另外一个线程,它一次只处理一个线程(太多的资源无法同时处理多个线程)。处理线程执行以下操作:

  • 从数据库中提取数据
  • foreach{PROCESS}
  • 如果计数=0{thread.suspend()}(由thread.resume()唤醒)
  • 重复
  • 我的工作线程执行以下操作:

  • 验证数据
  • 插入数据库
  • call Queue.Poke(队列名称)
  • 当我戳它时,如果线程被挂起,我将
    .resume()

    我担心的是,如果进程线程看到
    count==0
    ,我的工作线程就会插入并戳入,然后我的进程继续沿着if运行并休眠。它不会意识到数据库中有新的东西


    我应该如何写,这样我就不会有竞争条件。

    我想这可能是你需要的结构

    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
            }         
        }        
    }
    
    private readonly队列_Queue=new Queue();
    私有只读对象_Lock=新对象();
    void FillQueue()
    {
    while(true)
    {
    var dbData=new{Found=true,Data=new object()};
    if(dbData.Found)
    {
    锁
    {
    _排队(dbData.Data);
    }
    } 
    //如果队列中有多个线程,则
    //可能想把它节流一点,这样线程
    //处理队列不会受到限制。
    /如果1ms太长,考虑使用
    //TimeSpan.FromTicks(1000)。
    睡眠(1);
    }       
    }
    void ProcessQueue()
    {
    对象数据=null;
    while(true)
    {
    锁
    {
    数据=_Queue.Count>0?_Queue.Dequeue():null;
    }
    如果(数据==null)
    {
    睡眠(1);
    }
    其他的
    {
    //过程
    }         
    }        
    }
    
    我想这可能是您需要的结构

    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
            }         
        }        
    }
    
    private readonly队列_Queue=new Queue();
    私有只读对象_Lock=新对象();
    void FillQueue()
    {
    while(true)
    {
    var dbData=new{Found=true,Data=new object()};
    if(dbData.Found)
    {
    锁
    {
    _排队(dbData.Data);
    }
    } 
    //如果队列中有多个线程,则
    //可能想把它节流一点,这样线程
    //处理队列不会受到限制。
    /如果1ms太长,考虑使用
    //TimeSpan.FromTicks(1000)。
    睡眠(1);
    }       
    }
    void ProcessQueue()
    {
    对象数据=null;
    while(true)
    {
    锁
    {
    数据=_Queue.Count>0?_Queue.Dequeue():null;
    }
    如果(数据==null)
    {
    睡眠(1);
    }
    其他的
    {
    //过程
    }         
    }        
    }
    
    处理线程:

  • 事件。重置
  • 从数据库中提取数据
  • foreach{PROCESS}
  • 如果计数==0,则事件。请稍候
  • 重复
  • 另一条线:

  • 验证数据
  • 插入数据库
  • event.Set()
  • 您将有额外的唤醒(在空队列中唤醒,无需处理,返回睡眠),但不会错过插入。

    处理线程:

  • 事件。重置
  • 从数据库中提取数据
  • foreach{PROCESS}
  • 如果计数==0,则事件。请稍候
  • 重复
  • 另一条线:

  • 验证数据
  • 插入数据库
  • event.Set()

  • 您将有额外的唤醒(在空队列上唤醒,无需处理,返回睡眠),但您不会错过插入。

    他在这里所做的是使用队列作为通知机制,而不是OP考虑的线程.resume()。只要“队列中有东西”,循环就会运行以检查数据库。他在这里所做的是使用队列作为通知机制,而不是OP考虑的线程.resume()。只要“队列中有东西”,循环就会运行以检查数据库。我不理解event.Reset,什么event.Wait可能是(听起来好像我没有使用thread类)和event.set-hmm,如果这不匹配,那么event.Wait不会阻塞,除非事件被重置并清除。。。有趣。我应该使用什么类?event是一个ManualResetEvent实例,两个线程都有一个引用。关键部分是顺序:先处理重置,然后出列,然后工人先排队,然后设置。这确保了当处理进入睡眠状态并错过工作队列项目时没有窗口。我不了解event.Reset,什么event.Wait可能是(听起来好像我没有使用线程类)和event.set-hmm,如果这不匹配,则event.Wait不会阻止,除非事件被重置并清除。。。有趣。我应该使用什么类?event是一个ManualResetEvent实例,两个线程都有一个引用。关键部分是顺序:先处理重置,然后出列,然后工人先排队,然后设置。这确保了当处理进入睡眠状态并错过工作队列中的项目时,没有窗口。