C# 如何锁定同一组织中用户的请求
我们有一个多用户web应用程序。每个用户都属于他/她的组织,当然,组织可以有多个用户。我需要完成的是每个组织内文档的自动编号。以下是我迄今为止编写和测试的内容(下面的示例是一个测试用例,它增加了每个组织的计数器):C# 如何锁定同一组织中用户的请求,c#,multithreading,locking,C#,Multithreading,Locking,我们有一个多用户web应用程序。每个用户都属于他/她的组织,当然,组织可以有多个用户。我需要完成的是每个组织内文档的自动编号。以下是我迄今为止编写和测试的内容(下面的示例是一个测试用例,它增加了每个组织的计数器): 公共类HomeController:控制器 { 私有静态字典lockDictionary=新字典(); 私有静态只读对象锁定器=新对象(); 公共字符串锁(INTORGID) { 字符串路径=@“X:\org_389;”+orgId.ToString(); 锁(储物柜) { //检查
公共类HomeController:控制器
{
私有静态字典lockDictionary=新字典();
私有静态只读对象锁定器=新对象();
公共字符串锁(INTORGID)
{
字符串路径=@“X:\org_389;”+orgId.ToString();
锁(储物柜)
{
//检查orgId是否在字典中,否则添加它
如果(!lockDictionary.ContainsKey(orgId))
添加(orgId,newobject());
}
//如果同一组织中的其他用户尝试获取当前计数器,请等待当前用户完成
锁(锁字典[orgId])
{
字符串content=“1”;
//这只是测试写入文件。实际上
//代码为:从dbo.AuthOrg中选择计数器,其中orgId=x
//更新dbo.AuthOrg set Counter=Counter+1,其中orgId=x;
if(System.IO.File.Exists(path))
{
字符串fileContent=System.IO.File.ReadAllText(路径);
int counter=Convert.ToInt32(fileContent)+1;
content=counter.ToString();
}
System.IO.File.WriteAllText(路径、内容);
系统线程线程睡眠(1000*10);
}
返回System.IO.File.ReadAllText(路径);
}
}
我需要防止的是,来自同一组织的两个用户在获取和递增组织计数器时不设置竞争条件。我是通过使用锁来实现的
上面的代码有副作用吗
应用程序托管在IIS上,因此所有请求都可以使用
静态变量。为什么只使用密钥字典?使用哈希集
。此外,您可以使用ConcurrentDictionary
并避免锁定
您计划在将来的任何时候扩展您的API吗?@CamiloTerevinto以及如何使用HashSet
通过id锁定?@Evk现在我想起来了,您可能不能。但是对于ConcurrentDictionary
anyway@john现在不行。我可以对整个请求设置锁,就这样,但是性能对我来说很重要。尽管我需要检查sqlserver的配置模式(同时进行多个插入…)。
public class HomeController : Controller
{
private static Dictionary<int, object> lockDictionary = new Dictionary<int, object>();
private static readonly object locker = new object();
public string Lock(int orgId)
{
string path = @"X:\org_" + orgId.ToString();
lock (locker)
{
// check if orgId is in the dictionary, else add it
if (!lockDictionary.ContainsKey(orgId))
lockDictionary.Add(orgId, new object());
}
// if some other user within the same organization tries to get current counter, wait that current user finishes
lock(lockDictionary[orgId])
{
string content = "1";
// this is just testing to write to file. Actually
// the code will be: select counter from dbo.AuthOrg where orgId = x
// update dbo.AuthOrg set Counter = counter +1 where orgId = x;
if (System.IO.File.Exists(path))
{
string fileContent = System.IO.File.ReadAllText(path);
int counter = Convert.ToInt32(fileContent) + 1;
content = counter.ToString();
}
System.IO.File.WriteAllText(path, content);
System.Threading.Thread.Sleep(1000 * 10);
}
return System.IO.File.ReadAllText(path);
}
}