.net - 我应该如何从数据库表中实现多线程队列?

标签 .net message-queue

我的流程如下:

  • 用户登录到 Web 应用程序,这会将一个条目放入 UserQueue 表
  • Windows 服务每 x 秒轮询一次该表并处理每个项目
  • 处理后,该项目将从 UserQueue 表中删除

  • 这一切都适用于顺序处理,但我担心长时间运行的任务可能会阻塞所有其他用户的队列(这将是 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/

    相关文章:

    node.js - 提高 Amazon SQS 性能

    .net - 使用 .NET 字符串格式化,如何格式化字符串以显示零 (0) 的空白(空字符串)?

    .net - 访问绑定(bind)到 DataGridView 行的项目 (WinForms)

    .net - 如何获取 WCF 远程端点的 IP 地址?

    c# - 什么时候可以使用结构而不是类

    rabbitmq - 对于低端设置,RabbitMQ有什么好的替代品吗?

    c - 是否可以在没有消息循环的情况下运行窗口应用程序

    java - 在 IBM MQ in java 程序中创建主题

    .net - 使用.net RichTextEdit,但过滤数据类型?

    apache-kafka - 在序列/类图中将消费/生产事件表示为从微服务到消息队列[Kafka]的UML组件