感觉两种方式:
1、 队列item中增加一个成员变量,用于存储当前线程引用,在item进入队列之前将当前线程wait(),当item出列完成处理后item.thread.notify(),让请求线程继续执行返回结果。缺点:请求会阻塞等待,如果消费者线程处理慢,并发量大有可能耗尽线程
2、队列item中增加成员变量用于放置唯一标示符,response中将唯一标识符返回页面, 客户页面提示正在处理,然后在页面上通过setInterval 轮询请求处理结果, 在轮询URL中 带上唯一标示符,整个过程用AJAX提交
最近也有类似的功能需要实现,最初考虑的也是队列,不过后来觉得抢购的数量很少,说以就用加锁的方式实现,然后配合一个缓存,数目达到后就直接返回已结束。但是这样做不适合抢购的数量很多的情况。
之前也考虑过加锁,后来发现不合适,因为不是一个活动,活动比较多,但是所用的代码是一样的,所以才放弃这个方案
你的意思是说:异步任务如何回传执行给调用方?
对,现在就是不知道怎么样在结果处理完之后将结果返回
@魔沦殇: 你问题描述的很模糊,根本没办法精确回答的。
用户抢购时是等待,还是可以继续浏览其他页面?还是用户通过某个界面可以查看抢购结果?
@Treenew Lyn: 抢购时请求提交后就等待直到将此次结果返回给用户后结束
@魔沦殇: 有两种,一种你是采用了MQ或者Reids作为队列处理的话,你只能在等待的用户线程进行 while+thredSleep(),一般来说这个抢购处理线程不会处理太久,所以等待时间是可以接受的。
第二种,http://msdn.microsoft.com/zh-cn/library/system.threading.tasks.task(v=vs.110).aspx
如果不是这种需求,你可以继续回复我。将你具体预期实现的想法再次详细的描述,要不我不好做准确回答。
@Treenew Lyn: 不好意思啊,这段时间一直比较忙,一直没时间啊,最终决定使用task,在内部维护了一个Task的字典,每次开启时等待上一次的处理是否结束,开启后将更新这个字典将这一次的Task更新需要等待的task。另外用redis做队列的话怎么来通知线程操作已经完成?
用长连接Comet ,如果浏览器支持用Websocket什么的
用SignalR吧
长连接不在考虑范围