前辈指点一下 如何在ASP.Net 中使用队列处理并发

iiihavedone 2019-01-02 02:19:58
因为涉及到并发,新手以前没有处理过这种业务
比如要设计一个抢红包的页面
我的思路是是这样的
//查询红包剩余个数count和剩余额度num

//初始化队列
Queue q = new Queue(count);

lock(obj)
{
//入队操作
}
//分配红包

//出队

//更新数据库

一、我思路有问题,不清楚这个锁该加在哪里,我想的是应该加在入队操作,但是这样我好像没办法判断什么时候队满,如果把整个锁起来的话队列又没有意义了
二、队列是否需要全局缓存呢,比如发了十个红包,只有七个用户进来,还剩余了3个红包,那么下次是否就直接可以读缓存的队列,判断用户是否在队中来判断用户是否重复操作,或者是继续之后的操作

需要前辈指点一下
...全文
408 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
高并发的 web 服务端并发编程,以及 tcp 等等的网关消息处理编程,其实不能像你这样胡乱套用”队列“概念。正如你自己发现的,你不能等待队列满了再去做什么事情。其实就是按照”自然而然“的算法,针对每一个离散的、并发的处理,使用 lock 来同步并发操作,以免产生脏数据处理冲突。此时多线程并发编程处理机制仅此而已。 队列其实更多地是用在 Task 之类的编程上。
  • 打赏
  • 举报
回复
根本不存在那个所谓的”队列“。 所谓”生产者-消费者“模型,你也要看看它是什么姿势摆着拍摄的广告。它弄个控制台demo程序自己一个窗口里边先摆着初始化一堆想当然的”任务“入队,然后再在这个窗口打印结果,还凑合唬人,而根本不是实际的多用户并发的 http 消息请求 asp.net 程序。你自己其实一经发现了问题,只是不敢对过时的”生产者-消费者“队列质疑而已。
iiihavedone 2019-01-02
  • 打赏
  • 举报
回复
引用 5 楼 以专业开发人员为伍 的回复:
如果你搞明白 lock 编程机制(这是多线程编程的最基本机制),那么你就知道20年前一些老掉牙的c++和java书上所谓的"队列“有些是多么多余的了。在 .net 中,系统级的队列就是系统线程池,例如你是用 Task 等等,无不是高级的队列,可以同时把整个委托对象压入系统线程池去调度。那么在 .net 中已经封装了不下10中高级的线程调度算法,你用不着发明什么低级的队列。那么剩下的,就是容易产生一些空谈队列的现象了。例如你这个问题,根本不涉及什么队列概念。你只需要尽量让 lock 语句块尽量小,以便提高性能,在语句块中使用和改变红包的信息,就行了。队列是画蛇添足。

当然当你编写分布式服务程序时,红包是在集群上共享的,不是单台服务器进程独享的,所以不能这么编程。那个时候就又会有人说什么”队列“概念了。其实各种框架封装了高级的队列,所以我们要直截了当地用封装之后的 .net 概念,以免滥用”队列“这个词儿。

学习了,谢谢前辈
  • 打赏
  • 举报
回复
引用 3 楼 iiihavedone 的回复:
刚刚想到 我是不是可以不清空队列的缓存,直到这个队列满了再清,但是出现了问题是分配红包总不能等待队列满了再分配
每一个 http 请求都是并发的、随机的。你怎么在一个请求中去纠结”队列“?在一个 http 请求中怎么”等这个队列满了“再给当前的 http 反馈?这就根本不符合页面消息处理基本的概念了。
  • 打赏
  • 举报
回复
如果你搞明白 lock 编程机制(这是多线程编程的最基本机制),那么你就知道20年前一些老掉牙的c++和java书上所谓的"队列“有些是多么多余的了。在 .net 中,系统级的队列就是系统线程池,例如你是用 Task 等等,无不是高级的队列,可以同时把整个委托对象压入系统线程池去调度。那么在 .net 中已经封装了不下10中高级的线程调度算法,你用不着发明什么低级的队列。那么剩下的,就是容易产生一些空谈队列的现象了。例如你这个问题,根本不涉及什么队列概念。你只需要尽量让 lock 语句块尽量小,以便提高性能,在语句块中使用和改变红包的信息,就行了。队列是画蛇添足。 当然当你编写分布式服务程序时,红包是在集群上共享的,不是单台服务器进程独享的,所以不能这么编程。那个时候就又会有人说什么”队列“概念了。其实各种框架封装了高级的队列,所以我们要直截了当地用封装之后的 .net 概念,以免滥用”队列“这个词儿。
iiihavedone 2019-01-02
  • 打赏
  • 举报
回复
引用 2 楼 以专业开发人员为伍 的回复:
例如有一个
static List<红包> list = .......;
集合,那么代码
lock(list)
{
......
}
就可以保证同一时间(以 list 为锁信号)只有一个线程进入这个代码块,其它的被 lock 语句阻塞。例如需要从 list 取下一个红包的代码,因为逻辑上必须保证安全,就应该在这个代码块中。反过来说,代码应该尽快解锁,以便提高性能。

这时候不必纠结什么“队列”名词儿?你搞所谓的队列为的什么?说的标题党一点儿,不懂 lock 的人才过于纠结“队列”这个词儿,因为头脑中没有 lock 机制所以觉得队列就是 lock。


用队列的话就是想让用户可以快速响应,如果锁住了红包这一块,也就是说在lock中要做的操作如果多了,解锁就慢,那后面的人要等很久
iiihavedone 2019-01-02
  • 打赏
  • 举报
回复
刚刚想到 我是不是可以不清空队列的缓存,直到这个队列满了再清,但是出现了问题是分配红包总不能等待队列满了再分配

  • 打赏
  • 举报
回复
例如有一个
static List<红包> list = .......;
集合,那么代码
lock(list)
{
    ......
}
就可以保证同一时间(以 list 为锁信号)只有一个线程进入这个代码块,其它的被 lock 语句阻塞。例如需要从 list 取下一个红包的代码,因为逻辑上必须保证安全,就应该在这个代码块中。反过来说,代码应该尽快解锁,以便提高性能。 这时候不必纠结什么“队列”名词儿?你搞所谓的队列为的什么?说的标题党一点儿,不懂 lock 的人才过于纠结“队列”这个词儿,因为头脑中没有 lock 机制所以觉得队列就是 lock。
iiihavedone 2019-01-02
  • 打赏
  • 举报
回复

  
//初始化队列
Queue RedPool = new Queue(currentNUM);

//判断是否有缓存队列,如果存在缓存队列读取缓存队列
if (MyCache.GetCache("QUEUE") != null)
{
RedPool = (Queue)MyCache.GetCache("QUEUE");
}

lock (queue)
{
//如果用户不在队列中
if (!Queue.isInById(RedPool, Member.ID))
{
//入队操作
//如果红包池没有满
if (!RedPool.IsFull())
{
RedPool.In(Member);
//两小时红包失效
MyCache.SetCache("QUEUE", RedPool, 7200);
}
else
{
//来晚啦 红包被抢完了
return;
}
}
}
//分配红包金额操作

//出队操作

//更新数据库,清空缓存


我这样的思路有问题但是现在还没想通怎么修改

62,025

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧