2011-02-11 81 views
4

作爲開發人員,我還沒有使用OLE/COM很長一段時間,但是我目前需要使用C#程序中的一些第三方OCX代碼庫。使用C#.NET中的OCX進行線程安全

C#程序使用線程(它是一個TCP套接字服務器)。 OCX被標記爲Apartment線程模型。從我的閱讀中,我得出結論,如果我小心地爲每個線程創建每個OCX的一個實例,並且只從創建它的線程使用該實例,那麼我應該沒問題。

,確實也做到: -

myThread.SetApartmentState(ApartmentState.STA); 

啓動每個線程之前。

這應該足以確保安全使用OCX嗎?

我看到的症狀是,線程都可以創建OCX,但在顯然隨機的基礎上,準備和初始化OCX的調用失敗。他們似乎沒有回覆任何有用的信息,爲什麼。

任何人都可以解釋我所看到的,或給我一個指導,以安全地從線程代碼使用這些OCX?

或者,我應該放棄並在一個線程中創建每個和所有OCX的單個實例,並通過線程安全隊列或類似方式將所有調用發送給它們?

+0

萬一它很有用,實際的錯誤是RPC_E_SERVERFAULT 0x80010105「服務器引發異常。」 我懷疑這會有幫助,因爲這個錯誤是如此通用。 – JohnCC 2011-02-11 22:08:32

回答

1

將組件標記爲Apartment threaded只是組件開發人員的一個斷言。有很多組件開發人員都不懂線程,甚至那些懂線程的人也會錯誤地認識到,所以相信這種說法是一種信任行爲。

就我個人而言,我很擔心在多線程環境中使用第三方組件。除了那些我知道在多線程應用程序中有廣泛曝光,和/或我知道我可以得到足夠支持的應用程序。

如果您無法獲得組件開發人員或組件的源代碼的支持,並且您絕對需要使用它,那麼創建單個實例的選項可能是一個很好的實用解決方案。

1

你正在做的事情,控制用戶可能從來沒有做過。像VB6這樣的運行時環境是使用.ocx最常見的地方,不允許創建多個STA線程。控件內部的代碼很可能包含全局變量,而不需要進行任何必要的鎖定以確保安全。隨機失敗是結果。

拋棄它,.NET對System.Net命名空間的TCP有很好的支持。套接字,TcpClient和TcpServer類。

+0

OCX庫可能不是套接字服務器 – dvhh 2011-02-11 18:03:00

+1

我不介意downvote有原因。但它確實有一定的意義。 – 2011-02-11 18:08:19

+0

不是我的失望,但你的建議基本上是使用.NET技術來重寫OCX,如果你不確切知道OCX的功能,那麼這可能有點滑稽。不幸的是,我不得不處理通過TCP/IP實現未公開協議的第三方組件,重寫並不總是一個簡單的選擇。 – Joe 2011-02-11 18:36:02

0

公寓狀態應由COM管理,因此設置公寓狀態只涉及您的.Net代碼公寓狀態。 但你的COM對象的公寓只能從創建你的COM對象的線程(調用CoInitialize的那個線程)訪問。 至於對COM對象的調用失敗,它們可能來自底層代碼。什麼是你的OCX庫?