2013-10-26 65 views
4

請參閱從StreamWriter class specification採取以下警告:是MSDN引用system.thread,工作線程,I/O線程還是全部三個?

「任何公共static這種類型的成員(在Visual Basic中的Shared)都是線程安全的所有實例成員不能保證是線程安全的。」

我知道一個W3WC進程包含兩個線程池,即工作線程和I/O線程。工作線程可以包含自己的許多線程(如果應用程序創建自己的System.Thread實例)。

該警告僅與System.Threads有關,還是與工作線程和I/O線程相關Ie.因爲StreamWriter類的實例變量不是線程安全的,那麼這是否意味着如果多個工作線程訪問它,將會出現問題,例如,如果兩個不同Web客戶機上的兩個用戶同時嘗試寫入日誌文件,那麼是否可以鎖定另一個?

回答

3

如果一個類不是線程安全的,那麼你不能接受該類的一個實例並從多個線程使用該實例。無論他們是System.Threading.Thread還是ThreadPoolTask或IIS中的工作線程。它們都是線程 - 它們都是搶先式多任務處理,而對象處於不希望被搶佔的狀態。

雖然這在你描述的場景中並不重要。假設兩個Web客戶端試圖同時連接到服務器,並且您的請求處理程序嘗試登錄到一個文件,這意味着您有兩個線程可能試圖同時寫入該文件。但這不是線程安全問題,因爲在兩個線程中都不會使用相同的StreamWriter實例。 (至少,我希望不是 - 如果你有一個靜態的StreamWriter實例,你會怎麼知道什麼時候刷新它並關閉文件?跨線程共享同一個writer是沒有任何意義的。)

取而代之,每個線程應該創建它自己的StreamWriter,寫入它,然後關閉它。是的,仍然存在併發問題 - 如果第二個線程嘗試打開文件時第一個線程尚未關閉文件,則第二個線程將獲得文件共享異常,您需要捕獲該異常並重試 - 但這是一個文件鎖定問題,而不是線程安全問題。

+0

謝謝+1。如果說如果使用靜態變量或函數,工作線程和IO線程只能受線程問題影響,這是否公平? – w0051977

+0

不,您可以輕鬆地跨線程傳遞對象引用而不使用靜態。作爲一個例子,啓動線程可能會創建一個對象實例,然後將其傳遞(可能通過閉包中的變量捕獲)到在線程中運行的代碼中。任何你可能從多個線程訪問一個對象實例的地方,都需要注意線程的安全性,並在必要時添加鎖。 –

+0

謝謝。我沒有看到如何在工作線程中共享實例變量。你能提供一個例子嗎? – w0051977

相關問題