1. 程式人生 > >C#(Winform) 當前執行緒不在單執行緒單元中,因此無法例項化 ActiveX 控制元件

C#(Winform) 當前執行緒不在單執行緒單元中,因此無法例項化 ActiveX 控制元件

解決方案:

1、在主執行緒中例項化此ActiveX控制元件

2、將建立此Active控制元件的執行緒設定為單執行緒。

      Thread.ApartmentState 獲取或設定此執行緒的單元狀態。            

newThread= new Thread(MainFormMessageThread);

            newThread.SetApartmentState(System.Threading.ApartmentState.STA)

            newThread.Name = "ActiveXThread";

            newThread.Start();

或者執行緒池也可以

ThreadPool.QueueUserWorkItem(new WaitCallback(functionName), Obj);

如果不在單執行緒單元中,那就宣告為單執行緒單元
給Main函式加上[STAThread]

static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {

        }
}

Note:

       在 .NET Framework 1.0 版和 1.1 版中,ApartmentState 屬性將執行緒標記為指示將在單執行緒單元或多執行緒單元中執行。當執行緒處於 Unstarted 或 Running 執行緒狀態時,可以設定此屬性;但一個執行緒只能設定此屬性一次。如果尚未設定此屬性,則它將返回 Unknown。

     在 .NET Framework 1.0 和 1.1 版中,可以通過使用 System.Threading.ApartmentState 屬性線上程執行之後設定單元狀態;這樣會建立爭用條件。在 .NET Framework 2.0 版中,這是不允許的。

COM 元件使用單元來同步對資源的訪問。與之相對,託管物件使用同步區域、同步基元和同步上下文來確保以執行緒安全的方式使用所有共享資源,其中同步基元指互斥體、鎖和完成埠等物件。有關 .NET 執行緒模型的其他資訊,請參見託管執行緒處理。

為了實現互用性,公共語言執行庫將在呼叫 COM 物件時建立一個單元並將其初始化。託管執行緒可以建立並進入只包含一個執行緒的單執行緒單元 (STA) 或包含一個或多個執行緒的多執行緒單元 (MTA)。當 COM 單元與執行緒所生成的單元相容時,COM 將允許呼叫執行緒直接呼叫 COM 物件。如果這兩種單元不相容,COM 將建立一個相容的單元並通過代理將所有呼叫封送在新的單元中。

執行庫呼叫 CoInitializeEx 將 COM 單元初始化為 MTA 或 STA 單元。在 .NET Framework 2.0 版中,如果未在啟動執行緒之前設定託管執行緒的單元狀態,則託管執行緒會被初始化為 MTA。在啟動執行緒之前可使用 SetApartmentState 或 TrySetApartmentState 方法設定單元狀態。

在 .NET Framework 2.0 版中,除非將 STAThreadAttribute 應用於入口點過程,否則主應用程式執行緒會被初始化為 MTA。

下表將列出 ApartmentState 列舉值並顯示可比的 COM 單元初始化呼叫。

ApartmentState 列舉值

COM 單元初始化

MTA

CoInitializeEx(NULL, COINIT_MULTITHREADED)

STA

CoIntializeEx(NULL, COINIT_APARTMENTTHREADED)

未知

CoInitializeEx(NULL, COINIT_MULTITHREADED)