Chi*_*han 2 c# asp.net-mvc multithreading dynamics-crm dynamics-crm-4
假设我有以下代码将用户插入MVC应用程序中的MS Dynamics:
public bool CreateContact(string email)
{
if (crm.contacts.Count(x => x.Email == email) > 0)
return false; //Email already exist in the Crm. Skip
var contact = new contact {Email = email};
crm.AddTocontacts(contact);
crm.SaveChanges();
return true;
}
Run Code Online (Sandbox Code Playgroud)
它非常适合阻止用户使用相同的电子邮件地址注册,直到最近我们遇到Dynamics的主要性能问题.
显然,用户会遇到很大的延迟,并经常三次点击触发此代码的按钮.
问题是,.Count()在不同的Http请求中同时触发.SaveChanges()在第一个Request中完成.因此,我们看到的联系人具有相同的电子邮件地址.
虽然我已经从客户端添加了一个修复程序,但我想看看是否可以在服务器端完成此操作.
什么是使这个线程安全的好策略?
虽然在CRM中添加约束是最好的解决方案,但是我现在无法实现该解决方案,因为在发现此问题之前很久就存在CRM中的重复项.显然,有多个应用程序与CRM对话.
由于锁定和线程的经验很少,我最终做了以下事情:
internal static class ContactLock
{
internal static readonly object Locker = new object();
}
public bool CreateContact(string email)
{
lock(ContactLock.Locker)
{
if (crm.contacts.Any(x => x.Email == email))
return false; //Email already exist in the Crm. Skip
var contact = new contact {Email = email};
crm.AddTocontacts(contact);
crm.SaveChanges();
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
它通过我的单元测试,似乎没有任何问题.
这种验证通常应该由底层数据存储中的唯一约束支持.如果可以在CRM数据库中创建约束,那么修复应该在哪里.
您的代码段显示了需要某种锁定的典型位置.检查(带Count())和SaveChanges()应该由锁保护.我建议你先从锁定一个静态的对象开始 - 这意味着它将是一个防止同时注册的全局锁.如果这证明是一个问题,你可以修改锁定策略.
关于电话花了很多时间 - 这是你应该解决的问题.向电子邮件列添加唯一约束将强制将其编入索引,这可能会大大提高性能.如果可能(再次,我不知道CRM)你应该使用linq的Any()运算符而不是Count()检查是否存在.前者可以在第一次打击时打破,而后者则必须继续扫描.
| 归档时间: |
|
| 查看次数: |
1916 次 |
| 最近记录: |