ArcGIS Engine 10 for crossplatform C++ 程式 使用了多線程,在一個線程中使用 AO 的東西 都沒問題。
但是 如果在一個線程使用了AO 的license 初始化,在另外一個線程(在 license代碼之後開啟的線程)直接使用 AO的東西,這樣,直接報錯,com錯誤。
於是我搜尋了下:arcgis Engine C++ 多線程 ,雖然 不報什麼希望,因為 ArcEngine 的資料 少之又少。
結果看到了下面的文章,兩個文章內容一樣,前面是轉載,但是我先看到的。
http://blog.sina.com.cn/s/blog_5f08173901010brv.html
http://anshien.blog.163.com/blog/static/169966308201082441114173/
其中:
2、ArcObjects執行緒模式所有的ArcObjects組件都被標記為單一執行緒 Apartment(STA參考VS協助文檔)。每個STA都限制在一個線程中,但是COM並不限制每個進程中STA的數目。當一個方法調用進入一個STA,它被轉移到STA的唯一線程。因此,在STA中的一個對象將一次只接收和處理一個方法調用,它接收的每個方法調用會到達同一線程。ArcObjects組件是安全執行緒的,開發人員可把他們在多線程環境下使用。對於AO應用程式在多線程環境下有效運行,由AO所使用的線程單元模型,即獨立線程,必須加以考慮。該模型的工作原理是消除跨線程通訊。一個線程內所有ArcObjects對象的引用應當只與在同一個線程的對象進行通訊。對於此模型的運行,在ArcGIS 9.X中單個對象都被設計為線程唯一,而非進程唯一。在進程中管理多個對象的資源消耗超過由制止跨線程通訊所獲得的效能提升幅度。對於擴充ArcGIS系統的開發人員,所有對象甚至包括你創造的對象都必須遵循這一規則,孤立線程工作。如果你建立的對象做為開發的一部分,你必須確保它們是線程唯一,而不是進程唯一。線程唯一就是防止跨線程通訊,這裡ArcGIS Engine中多線程的首要規則。
這意思 就是 所有AO的東西 應該放到一個線程 幹活,不能跨線程 使用AO 的com組件。
好吧,我無語了,這問題 無解了。。真是不明白,為什麼要限制 在一個線程內。
正如 後一篇文章 留言:
寫的很好,前不久用AE開發遇到了多線程的問題,一直沒有解決。最後放棄了,返回到單線程的開發。 COM對象和多線程一起使用還是很麻煩的,看了您的文章,很有收穫。
AE 和 多線程 ,就是 麻煩。最終 還是 COM 物件 的錯。
不知道 我是否 理解錯了。。
----------------
這個 要AE 在多線程 可以使用,互補打擾,也可以,那就是 對線程 進行 下小小的修改 ,設定線程的屬性 為 STA
兩種執行緒模式:STA和MTA。
STA(single threaded apartments)。apartment只是一個邏輯上的概念,它可以包含一個或多個線程。一個AppDomain可以包括一個或多個apartment。STA是指該apartment中只能包含一個thread。
MTA(multi threaded apartments)。指該apartment中可以包含多個thread。
STA and MTA 之間最大的區別就是MTA 可以在同一個apartment 中使用所有的共用資源並發執行多個線程。 而多個STA雖然可以共用資料,但是不能並發執行線程,存在效能問題。
具體 搜尋:STA MTA 即可。
Single-Threaded ApartmentsA process has one single-threaded apartment (STA) for each thread that called CoInitialize. Each of these apartments, in turn, may have zero or more COM objects associated with them. As the name implies, however, only one specific thread (the thread that created the apartment by calling CoInitialize) may directly access the objects within the apartment. Once associated with an apartment, a thread cannot be associated with another apartment or change the concurrency model of its apartment.To create an STA, a thread simply calls CoInitialize or CoInitializeEx(NULL, COINIT_APARTMENTTHREADED), thereby associating the calling thread with the apartment until it calls CoUninitialize. Successive calls to either of these functions by the same thread do not create additional apartments or enable you to change the concurrency model of the apartment.Multi-Threaded ApartmentsAlthough multi-threaded apartments, sometimes called free-threaded apartments, are a much simpler model, they are more difficult to develop for because the developer must implement the thread synchronization for the objects, a decidedly nontrivial task. On the positive side, removing an STA's synchronization mechanism gives the developer much finer control over the use of thread synchronization. They can apply it where it is actually needed rather than taking the very conservative approach of STAs, which synchronize access to the entire apartment.The first thread in a process to call CoInitializeEx(NULL, COINIT_MULTITHREADED) creates a multi-threaded apartment that will be shared with any other threads that repeat this call. Once a thread is associated with the MTA, it can directly access any object created therein, which introduces some subtle variations from the way STAs operate. In STAs, a specific thread, permanently associated with the apartment, creates an object and only this thread can ever access the object (as discussed in the preceding section). In an MTA, however, many threads may create objects in the apartment and no thread controls access. As a result, it is possible to have several threads simultaneously access an object and change class data; hence the need for synchronization objects to protect class data.It should come as no surprise that, as with STAs, global data is not thread-safe in an MTA and always needs to be adequately protected. Remember to take advantage of the inherently thread-local nature of local and automatic variables: they're allocated on the thread's stack and consequently do not need to be protected.In-process components written for MTA use the ThreadingModel registry value (ThreadingModel = Free) to indicate to clients that they should be created in the MTA. An in-process component marked as such will be created in the MTA, regardless of the apartment type of the client. If necessary, COM will create the MTA before creating the component. CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)CoUninitialize()CoInitializeEx(NULL, COINIT_MULTITHREADED)摘自:Understanding and Using COM Threading Modelshttp://msdn.microsoft.com/en-us/library/ms809971.aspxhttp://msdn.microsoft.com/zh-cn/library/ms809971.aspx
http://social.msdn.microsoft.com/search/en-US?query=STA
http://msdn.microsoft.com/en-us/library/windows/desktop/ms680112(v=vs.85).aspx
主要就是在 線程 中 加入 CoInitlizeEx 函數,指定 設定 STA屬性 就行。