我已经构建了增强WebApi服务(MvcApplication)的UserName和电子邮件。
我有这个服务的网址:
Ex: www.domain.com/Controller/SendUser我有一些分支机构使用这个URL到我的服务在他们的网站/登陆页面,他们发送给我的数据与用户名,和电子邮件的潜在客户。
一些分支机构已经构建了它们提交错误的表单,并允许用户在看到屏幕上的响应或重定向到出现问题的下一个page.And之前多次按“发送”按钮。
我用重复的数据向我的服务发出5-10请求,并开始运行我的所有验证函数和方法插入到数据库。
重要:我不会在数据库级别上解决方案,我想在开始时停止请求,甚至不启动所有的验证服务。
我需要接收请求,临时保存UserName+Email,如果我在相同的秒内或在接下来的10秒内接收到相同的UserName+Email,这只是为了避免它。
我尝试将静态字典添加到Global.asax中并保存EncodedLead(从User+Email),在检查是否ContainsKey(X)之前,我锁定字典GlobalMemoryLeads,而不是添加一个键,但是即使在字典被锁定时,我仍然会遇到一些错误--键已经准备好了。
线程似乎会抛出锁并尝试添加相同的键,即使GlobalMemoryLeads.ContainsKey(EncodedLead)返回false,另一个线程也可以将键添加到被另一个线程锁定的字典中??这里缺少什么?
如何避免重复请求?
已更新
我的代码:
[AcceptVerbs(WebRequestMethods.Http.Get, WebRequestMethods.Http.Post)]
[AllowCrossSiteJson]
public ActionResult SendUser(string UserName, string Email, )
{
string response = "";
bool duplicate=false;
try
{
string Lead = UserName + email;
int EncodedLead = Lead.GetHashCode();
//here i lock my GlobalMemoryLeads dictionary
lock (MvcApplication.GlobalMemoryLeads)
{
//here i check if that key is all ready ContainsKey
if (!MvcApplication.GlobalMemoryLeads.ContainsKey(EncodedLead))
{
try
{
MvcApplication.GlobalMemoryLeads.Add(EncodedLead, false);
}
catch (Exception ex)
{
//here i get error that key is all ready exist
//how it possible if i have
//1: Globalizes lock
//2 i check ContainsKey before
return Json(new { respondNotSuccess = "Duplicate Lead" });
}
}
}
}
catch (Exception ex)
{
response = "Exception " + ex.Message;
}
return Json(new { respondSuccess = response });
}发布于 2017-08-22 09:58:37
通常,避免锁定公共类型或代码无法控制的实例。
常见构造lock ( this )、lock (typeof (MyType))和lock ("myLock")违反了这个准则:
最佳实践是定义要锁定的私有对象或私有静态对象变量,以保护所有实例所共有的数据。
试着去做这样的事情:
private Object thisLock = new Object();
lock (thisLock)
{
if (!MvcApplication.GlobalMemoryLeads.ContainsKey(EncodedLead))
{
try
{
MvcApplication.GlobalMemoryLeads.Add(EncodedLead, false);
...https://stackoverflow.com/questions/45726892
复制相似问题