“不支持一个STA线程上针对多个句柄的WaitAll。”的解决方案

一、异常提示

不支持一个 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]属性即可支持多线程操作.

注明:此文的观点借鉴于互联网非原创。 

原文地址:https://www.cnblogs.com/sunxi/p/5577670.html