一、異常提示
不支持一個 STA 線程上針對多個句柄的 WaitAll。
出錯界面如下圖:
二、解決方法
先直接上解決方案吧。其實解決方法很簡單如下面的代碼直接把main函數的[STAThread]屬性注釋掉就行了。或者把[STAThread]替換成[MTAThread]
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; namespace Sx.WF { static class Program { /// <summary> /// 應用程序的主入口點。 /// </summary> //[STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainFm()); } } }
原理分析
經過研究MSDN,發現,在控制台程序的每個主函數Main之前,都有一個[STAThread]方法屬性,該屬性標識當前控制台程序的線程模型為單線程,因此在該模型下編寫多線程程序,並不能很好的兼容.具體的說明如下:
STAThreadAttribute
指示應用程序的 COM 線程模型是單線程單元 (STA)。
將此屬性應用於入口點方法(C# 和 Visual Basic 中的 Main() 方法)。它對其他方法無效。若要設置在代碼中啟動的線程的單元狀態,請在啟動線程前使用 Thread..::.SetApartmentState 方法。
注意:
在 .NET Framework 1.0 版和 1.1 版中,在啟動線程之前設置 Thread..::.ApartmentState 屬性。
COM 線程模型只適用於使用 COM interop 的應用程序。如果將此屬性應用到不使用 COM interop 的應用程序,將沒有任何效果。
COM 線程模型可設置為單線程單元或多線程單元。如果應用程序線程實際調用了 COM 組件,則僅為 COM interop 初始化該線程。如果沒有使用 COM interop,則不初始化該
在此說明中,有明確標識"COM 線程模型只適用於使用 COM interop 的應用程序。如果將此屬性應用到不使用 COM interop 的應用程序,將沒有任何效果。"因此,嘗試將該屬性刪除,編譯運行成功.問題解決.
解決:
因為在默認的.NET程序在創建時都默認被設置線程模型為單線程單元,即STA,故在不涉及到COM相關操作的情況下,可以去掉控制台程序Main 上的[STAThread]屬性即可支持多線程操作.
注明:此文的觀點借鑒於互聯網非原創。