首先让咱们体验一下频繁操做:服务器
1)打开项目,在后台aspx.cs等服务器页面,设置断点.并发
2)点击页面按钮this
3)调试开始进入断点,而后重复点击页面按钮spa
4)服务器第一次事件已经处理完毕,调试再次进入了断点,而后再进行处理线程
而后就出现了多条数据的新增问题.调试
使用lock也将没法解决该问题.由于lock是解决并发问题的,不是解决频繁操做的问题的.code
所以这里我要说一下并发操做和频繁操做.并发是多个线程同时进行操做,频繁操做是指一个操做未响应到客户端,另外一个操做再次重复进行,它们是2个不一样的概念.server
并发问题处理方法blog
你们可能很熟悉这个代码:队列
public class Singleton { private volatile static Singleton _instance = null; private static readonly object lockHelper = new object(); private Singleton(){} public static Singleton CreateInstance() { if(_instance == null) { lock(lockHelper) { if(_instance == null) _instance = new Singleton(); } } return _instance; } }
对于并发,咱们主要作的事情是:让一个线程跑完以后再跑另外一个线程,所以须要加锁
加锁使用了lock关键字,lock就是把{}中的代码段锁定,防止多个线程同时运行该代码段.
咱们通常对于普通并发,使用lock就能够解决了,可是若是是秒杀的这种状况呢。
咱们这时候须要使用队列集合去进行操做.
频繁操做处理方法:
咱们想象一下:第一次点击按钮,假设生成了一个操做会话OperSA1,服务器执行第一次按钮操做的事件,执行未完成时,再次点击该按钮,
生成第2个操做会话OperSA2,服务器操做等待中.第一次按钮事件操做完成以后,客户端尚未响应这时候服务器就忙着执行第2次按钮事件了。
咱们认为服务器执行操做是有错的,错在第1次按钮事件执行完成以后没有当即响应给客户端就执行第2次操做了。但是服务器认为它自己是没有错的。
它认为错的是客户端,客户端操做频繁了。这时候怎么办呢?
咱们不如给服务器和客户端定一个操做约定:
在客户端定义一个会话标识符OperFrequent,若是客户端执行了第一次操做,则会话标识符OperFrequent生成标识,若是客户端再次执行了操做,可是会话标识符标识已经生成,则终止该操做。这是客户端的约定。
服务器在接到请求后,执行操做,操做完成后,清理客户端标识符。这是服务器的约定。
因此服务器必须在实际响应客户端以后才能修改客户端的会话标识符。
代码:
会话标识符定义:
responseVal就是OperFrequent
<input type="hidden" id="responseVal" value="none" runat="server" />
客户端执行操做:
if (document.getElementById('responseVal').value == 'none') { document.getElementById('responseVal').value = 'change'; // 触发服务器事件 }
服务器响应操做:
this.responseVal.Value = "none";