C# 如何处理此(db)队列争用情况?
基本上,我有多个线程,通过SQLite将数据添加到队列中。我还有另外一个线程,它一次只处理一个线程(太多的资源无法同时处理多个线程)。处理线程执行以下操作:C# 如何处理此(db)队列争用情况?,c#,multithreading,sqlite,C#,Multithreading,Sqlite,基本上,我有多个线程,通过SQLite将数据添加到队列中。我还有另外一个线程,它一次只处理一个线程(太多的资源无法同时处理多个线程)。处理线程执行以下操作: 从数据库中提取数据 foreach{PROCESS} 如果计数=0{thread.suspend()}(由thread.resume()唤醒) 重复 我的工作线程执行以下操作: 验证数据 插入数据库 call Queue.Poke(队列名称) 当我戳它时,如果线程被挂起,我将.resume()它 我担心的是,如果进程线程看到count==0
.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);
}
其他的
{
//过程
}
}
}
处理线程:
您将有额外的唤醒(在空队列上唤醒,无需处理,返回睡眠),但您不会错过插入。他在这里所做的是使用队列作为通知机制,而不是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实例,两个线程都有一个引用。关键部分是顺序:先处理重置,然后出列,然后工人先排队,然后设置。这确保了当处理进入睡眠状态并错过工作队列中的项目时,没有窗口。