2009-02-18 54 views
10

backgroundworker線程是否被重新使用?線程本地存儲在backgroundworker調用之間是否持久?

具體來說,如果我在背景工作者的DoWork()方法期間設置了一個命名的數據槽(線程本地存儲),那麼該數據槽的值將持續存在,有可能在稍後的時間被其他線程找到?

我不會這樣想,但我有這個錯誤......

編輯:This blog post表明BackGroundWorker利用ThreadPool,這意味着線程重新使用。所以問題就變成了;重用線程可能會在調用之間持久存儲線程本地存儲?

回答

7

當線程池重用一個線程時,它不會清除線程本地存儲器中或使用ThreadStaticAttribute屬性標記的字段中的數據。因此,通過一種方法放置在線程本地存儲中的數據可以暴露給由同一個線程池線程執行的任何其他方法。訪問由ThreadStaticAttribute屬性標記的字段的方法可能會遇到不同的數據,具體取決於哪個線程池線程執行它。

來源: http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx

0

如果沒有在MSDN中指定它,需要檢查源(或通過Reflector)以確定它。

如果未指定,則不能依賴當前行爲在未來版本的.NET中不會更改。

編輯:看起來像是使用線程池,所以線程被重用。

4

好,內部BackgroundWorker使用BeginInvoke這意味着(我相信),它使用從ThreadPool一個線程。至於如果TLS在線程返回池時被清除,我不能肯定地說。

爲了響應編輯,我在Reflector中看到的任何內容都暗示TLS插槽一旦返回到池就被清除或釋放。所以你必須在你的DoWork方法返回之前明確地清除它們。

+2

TLS當線程返回到線程池 「當線程池中重用線程,它不會清除在線程本地存儲或數據不被清除因此,當一個方法檢查線程本地存儲或使用ThreadStaticAttribute屬性標記的字段時,它找到的值可能是早期使用線程池線程時遺留下來的。 `SOURCE:[link](http://msdn.microsoft.com/enus/library/system.threading.threadpool.aspx)` – Taher 2013-02-07 12:22:08

相關問題