2012-01-18 26 views
4

我爲我的最新項目使用了MSpec,總體而言,我非常滿意。但是,當我的測試以並列方式運行時,我確實遇到併發問題,我想知道是否有人遇到了這個問題,或者更好的解決方案?MSpec:如何使靜態變量線程安全?

MSpec嚴重依賴靜態方法和變量來工作。

現在看來,當我在我的基類中定義了多個測試類使用的靜態變量,並且我以平行方式運行我的測試時,它們共享相同的靜態變量,從而干擾了彼此。

我正在使用NCrunch和Resharper作爲我的testrunner,並且遇到了這兩個問題。

任何人都熟悉這個問題?

+0

是不是像http:// sta一樣ckoverflow.com/questions/1254750/i-need-to-create-a-thread-safe-static-variable-in-c-sharp-net? – PKeidel 2012-01-18 09:46:03

+0

你可以請一個簡單的例子/複製。我想將其包含在我們的示例中。謝謝! – 2012-01-19 11:43:58

回答

0

默認情況下,靜態字段不是線程安全的。爲了使它們線程安全,您可以使用[ThreadStatic]屬性修飾它們。

查看ThreadStaticAttribute Class at MSDN瞭解更多信息。

+3

ThreadStatic爲每個線程創建一個獨立的靜態字段,這嚴格地說與線程安全不同,確保每個調用者都可以安全地調用靜態字段。我建議使用靜態屬性,並在get和set方法中確保線程安全 – hcb 2012-01-18 09:34:33

1

首先,我會推薦閱讀Thead Safety Guidelines on MSDN。這將使您很好地瞭解如何以及爲什麼在C#中使方法線程安全。

以下規則概述執行線程設計準則:

  • 避免提供改變靜態靜態方法。在常見服務器場景中,靜態狀態是跨請求共享的,這意味着多個線程可以同時執行該代碼。這爲線程化bug提供了可能性。考慮使用將數據封裝到不通過請求共享的實例中的設計模式。
  • ...添加鎖定以創建線程安全代碼會降低性能,增加鎖定爭用並創建死鎖錯誤發生的可能性
  • 請注意鎖定節中的方法調用。當A類中的靜態方法調用B類中的靜態方法時,可能會導致死鎖,反之亦然。如果A和B都同步它們的靜態方法,這將導致死鎖。只有在繁重的線程壓力下才能發現這種僵局。
  • 請注意鎖語句的問題(Visual Basic中的SyncLock)。使用鎖定語句解決所有線程問題很誘人。然而,System.Threading.Interlocked類是上級更新必須是原子的...

作爲一般的紙條,我更喜歡使用的方法(如果可能)是使一個方法(靜態或以其他方式)immutable。要做到這一點,所有變量應該是本地的(在堆棧上本地創建,或作爲參數傳遞給方法)。通過確保只使用局部變量,或者成員變量不可變,每個線程將在其自己的隔離區中運行,並且更改爲變量不會影響另一個線程。這是我在.NET仿真軟件中廣泛使用的一種方法,可以在C#中實現無鎖且高性能的多線程處理。

或者,如果變量必須是成員變量,並且可以通過鎖定關鍵字保護對它們的可變訪問權限。小心使用鎖會導致上下文切換(減慢)並引入死鎖情況的可能性。它也沒有保證線程安全,因爲鎖的使用必須防止您試圖防止的特定情況。

進一步的閱讀我建議看這些相關的問題,這說明線程安全性和不變性在C#:

最好的問候,