Asp.net C#.NET中函数锁定部分的复查
我锁定函数一部分的这段代码正确吗?或者当多个会话同时要求同一个考试时,它会有使用缺陷吗 其目的是,第一个请求检查的客户端将组装它,所有下一个客户端将获得缓存版本Asp.net C#.NET中函数锁定部分的复查,asp.net,caching,Asp.net,Caching,我锁定函数一部分的这段代码正确吗?或者当多个会话同时要求同一个考试时,它会有使用缺陷吗 其目的是,第一个请求检查的客户端将组装它,所有下一个客户端将获得缓存版本 public Exam GetExamByExamDto(ExamDTO examDto, int languageId) { Log.Warn("GetExamByExamDto"); lock (LockString) { if (!ContainsExam(examDto.id, langu
public Exam GetExamByExamDto(ExamDTO examDto, int languageId)
{
Log.Warn("GetExamByExamDto");
lock (LockString)
{
if (!ContainsExam(examDto.id, languageId))
{
Log.Warn("Assembling ExamDto");
var examAssembler = new ExamAssembler();
var exam = examAssembler.createExam(examDto);
if (AddToCache(exam))
{
_examDictionary.Add(examDto.id + "_" + languageId, exam);
}
Log.Warn("Returning non cached ExamDto");
return exam;
}
}
Log.Warn("Returning cached ExamDto");
return _examDictionary[examDto.id + "_" + languageId];
}
我觉得这不是解决问题的方法。永远不要锁定字符串-它们是不可变的,并且是固定的,因此当尝试在其他地方访问相同的字符串时,您可能会锁定整个应用程序 只需使用新的
对象
作为锁定:
private readonly object Padlock = new object();
请参阅Tess Ferrandez的博文。LockString变量,它真的是字符串吗?您不应该锁定一个字符串,因为您可能最终会遇到与字符串实习相关的问题,这将导致多个锁被锁定
另一件事是,锁中似乎有很多代码,这意味着你锁的时间比你可能不得不锁的时间长。如果可以,尝试从锁中取出尽可能多的代码。看起来基本上没问题,但不应该锁定
字符串。实习使得很难控制哪个实例是哪个实例。只需创建一个单独的对象来锁定:
private object padLock = new object();
此外,您还可以使用双重检查(在缓存检查后,监视器将不会调用锁):
安德鲁,我现在用你的调整来检查性能。啊,我们只是在调查你的代码有问题。这可能不是线程安全的。@Lieven,不过,这是优化,除非你真的有速度问题,否则我会还原到你的原始代码。双重检查锁定经常被证明是被破坏的。@Henk,你能给出这样的检查何时会被破坏的例子吗?下面是Java的链接,在.NET中它取决于内存模型等。
public Exam GetExamByExamDto(ExamDTO examDto, int languageId)
{
Log.Warn("GetExamByExamDto");
if (!ContainsExam(examDto.id, languageId))
{
lock (LockString) // Here should be some private locking object.
{
if (!ContainsExam(examDto.id, languageId))
{
Log.Warn("Assembling ExamDto");
var examAssembler = new ExamAssembler();
var exam = examAssembler.createExam(examDto);
if (AddToCache(exam))
{
_examDictionary.Add(examDto.id + "_" + languageId, exam);
}
Log.Warn("Returning non cached ExamDto");
return exam;
}
}
Log.Warn("Returning cached ExamDto");
return _examDictionary[examDto.id + "_" + languageId];
}
}