2010-03-15 13 views
0

這段代碼在哪裏鎖定了一部分函數是否正確?或者當多個環節同時詢問相同的考試時,它是否會有缺點?在C#.NET中函數的鎖定部分的回顧

目的是首先要求考試的客戶將組裝它,所有下一個客戶將獲得緩存版本。

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]; 
} 

我有一種感覺,這不是做這件事的方法。

回答

5

永遠不要鎖定字符串 - 它們是不可變的,因此當試圖在別處訪問相同的字符串時,最終可能會鎖定整個應用程序。

只需使用一個新的object爲您鎖定:

private readonly object Padlock = new object(); 

見苔絲Ferrandez this博客文章。

2

LockString變量,它真的是一個字符串嗎?您不應該鎖定字符串,因爲您最終可能會遇到與字符串實習相關的問題,這會導致多個鎖定鎖定。

另一件事是,鎖裏面似乎有很多代碼,這意味着你鎖定的時間比你可能必須更長。如果可以的話,儘可能多地從代碼中取出代碼。

2

它看起來基本沒問題,但你不應該鎖定string。實習使得很難控制哪個實例是哪個實例。只要創建一個單獨的對象鎖定在:

private object padLock = new object(); 
1

您也可以使用雙檢查(考試被緩存後Monitor.Lock不會在所有調用的):

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]; 
    } 
} 
+0

THX,安德魯,我現在用你的調整來檢查性能。 – 2010-03-15 15:16:16

+0

你確定'ContainsExam'是線程安全的嗎? – 2010-03-15 15:20:28

+0

啊,我們只是在看你的代碼有問題。它可能不是線程安全的。 – 2010-03-15 17:32:04