2012-06-29 68 views
1

我正在嘗試實現許多使用ReaderWriterLockSlim進行線程安全的屬性。 所以最喜歡我結束了我的所有屬性是這樣的:在很多屬性中使用ReaderWriterLockSlim的更簡單的方法

public string Name 
{ 
    get 
    { 
     rwLock.EnterReadLock(); 
     try { 
      return name; 
     } 
     finally { 
      rwLock.ExitReadLock(); 
     } 
    } 
    set 
    { 
     rwLock.EnterWriteLock(); 
     try { 
      name = value;      
     } 
     finally { 
      rwLock.ExitWriteLock(); 
     } 
    } 
} 

這種感覺非常詳細,並在10種性質重複的,所以我要尋找一個更乾的實現。

顯而易見的解決方案是將其封裝到釋放對dispose的鎖定的類中,並允許將我的線程安全操作放入using語句中。顯然,根據this和其他一些來源,這不是很安全。

所以我試圖拿出一個好看的解決方案使用lambda表達式和匿名方法:

private TResult ThreadSafeRead<TResult>(Func<TResult> value) 
{ 
    rwLock.EnterReadLock(); 
    try { 
     return value(); 
    } 
    finally { 
     rwLock.ExitReadLock(); 
    }    
} 

private void ThreadSafeWrite(Action value) 
{ 
    rwLock.EnterWriteLock(); 
    try { 
     value(); 
    } 
    finally { 
     rwLock.ExitWriteLock(); 
    } 
} 

public string Name 
{ 
    get { return ThreadSafeRead(() => name); } 
    set { ThreadSafeWrite(() => { name = value; }); } 
}  

雖然這消除了重複代碼,這是討厭我,我不知道,如果它是作爲線程像我最初的詳細實施一樣安全。

有沒有人對MSIL有更深入的理解,這將會產生多線程 理論能夠告訴我我的實現是否安全?

+1

這與線程安全無關。問題來自你的線程調用Thread.Abort。 – usr

回答

1

的常用方法我見過的人去了解,這是通過在物體包裹鎖和做線沿線的東西:

using (var obj = new ReadOnlyLock(this.rwLock)) 
{ 
    this.name = value; 
} 

我承認我不這樣做(爲什麼創建另一個對象只是鎖定?),但它確實實現了更好的風格目標,有些人認爲最重要的是...

+0

正如我所提到的,封裝使用語句是顯而易見的解決方案,但我發現許多消息來源都解釋說它不是線程安全的。見[這裏](http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=21)。 – KrisG

+0

對不起,我不是故意暗示它是完美的。我不使用它。相反,我只是說這是用於解決您的問題的一種常見*模式。 我會承認,我不認爲這是一個真正值得解決的問題... –

+1

@KrisG:廢話,爲什麼不是線程安全的? (您鏈接的文章描述了try-finally的一般問題...) – Cameron

0

在您的博客文章中提到的問題確實存在,是的。有關此主題的更徹底的處理,請參閱Joe Duffy's post

您的代碼是否會遭受異步異常?很有可能它們只發生在ASP.NET下運行,並且當前請求由於超時而中止。當然,你不應該出於各種原因自己放棄一個線程。

我不認爲你應該切實關心這個問題。

相關問題