注:凡是注日期的材料,一定要在底部閱讀更新變化的.NET 4.6
是的,這是一種常見的請求但它不可用。 Windows總是將操作系統線程初始化爲系統默認的LCID,在控制面板中的區域和語言選項小程序中進行配置。只要您自己創建線程,就可以覆蓋它。但是對於線程池線程和線程來說,這可能是由運行你的進程的某種非託管代碼(例如COM服務器)創建的。
後一種情況是問題所在。運行由非託管代碼創建的線程上的託管代碼時,.NET沒有問題。但是它不能對線程初始化的方式做任何事情。對於CurrentUICulture來說也是如此,但對於Thread.SetApartmentState()等更隱晦的東西也是如此。不要低估這種線程在您的程序中運行代碼的可能性,由微軟編寫的COM服務器非常高興。
你將不得不通過你的代碼精細齒梳,並找到任何代碼可能在你沒有創建的線程上運行。任何事件處理程序都是可疑的,就像任何具有回調的BeginXxx()方法一樣。 BackgroundWorker絕對是一個較小的問題。
不壓倒線程的文化可以產生很微妙和難以診斷bugz。一個很好的例子是一個SortedList,它是一個字符串的鍵。當運行錯誤的文化時,它隨機將無法找到實際存在於列表中的元素。由於排序規則不同,導致列表不再被排序在另一種文化中。
如果我設法嚇唬你,那麼我得到了我的信息。這發生在我身上,用一個在丹麥機器上運行不正常的非常大的程序來調試問題。我們沒有丹麥本地化,並強制用戶界面以英文運行。工作者線程使用了一個以字符串作爲關鍵字的紅黑樹。當被要求與Åårdvårks打交道時,它隨機失敗。花了我一個星期。
更新:此問題已在.NET 4.5中解決。 CultureInfo類現在有一個DefaultThreadCurrentCulture和DefaultThreadCurrentUICulture。設置時,它將用於初始化任何託管線程的文化,而不是默認的Windows系統文化。它究竟是如何與本地代碼開始的線程進行交互並輸入托管代碼的,我還不清楚。
更新:此問題在.NET 4.6中有更徹底的解決方案。文化現在自動流動,理想的行爲。 MSDN文章CultureInfo.CurrentCulture()談論它。提供的信息仍然令人困惑,實驗上,它似乎也流向了一個Thread對象,而不僅僅是一個Task或線程池線程,並且不使用DefaultThreadCurrentCulture。前進兩步,退一步,建議測試。