我的流程如下:
这一切都适用于顺序处理,但我担心长时间运行的任务可能会阻塞所有其他用户的队列(这将是 Web 应用程序的问题)。
我认为 .NET 中的 BlockingCollection 将项目保存在内存中,然后处理它们,但我不能保证 UserQueue 表中的一行不会多次放入该集合中(由于 BlockingCollection 的非唯一性)除非我使用数据库标志(例如,BeingProcessed = true)。我不热衷于数据库标志,因为如果我的服务因任何原因停止,它可能会在BeingProcessed = true 的表中留下未处理的项目。
有没有更标准的方法我错过了,或者我应该考虑 Quartz.net 或类似的方法吗?
最佳答案
基本技巧是使用带有日期的测试和设置,而不仅仅是一个简单的 bool 值。这是你如何做到的。
假设您的 UserQueue 表非常简单。目前是这样的:
create table UserQueue (id integer primary key, description varchar not null)
到现在为止还挺好。但是我们想安全地捕获一个任务并用它做点什么。
首先,让我们稍微改变一下架构:
create table UserQueue (id integer primary key, description varchar not null,
dtLocked datetime null)
现在,我们只需遵循一个简单的过程:
select * from UserQueue limit 1
申请的工作NOW()
通过例如它当前为空的地方update UserQueue set dtLocked = NOW() where id = @id and dtLocked is null
因为我们现在使用
datetime
对于锁,我们可以通过简单的更新语句定期清除死任务,该语句删除超过一定时间(例如五分钟)的锁。作为奖励,这种设计让您可以一次安全地处理多个任务,因此您可以通过简单地启动更多线程来消除用户任务阻塞的任何机会。
关于.net - 我应该如何从数据库表中实现多线程队列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8684287/