`

探秘System.Threading序列 - 第一篇:从Thread的线程单元状态ApartmentState说起

阅读更多

System.Threading命名空间是.Net多线程编程的基础。对于多线程编程在实际工作中一直用的不多,所以了解也就不多。尽管如此,随着多核,多个cpu的出现,大计算量的需要,多线程将越来越受关注。所以打算写个系列博客,以便更多的了解学习多线程的知识。听说.Net4.0中有一个更方便多线程的类库,可惜还没真的见识过,先熟悉System.Threading就当“温故而知新”了

 

第一篇:从Thread的线程单元状态ApartmentState说起

 

ApartmentState是一个枚举变量,用来设置线程的单元状态(单元状态的ApartmentState的中文msdn翻译,这个翻译很水,我不能从这四个汉字中确切的了解英文ApartmentState要表达的意思)。ApartmentState有三个枚举值,分别为STA:表示Thread将被创建并进入一个单线程单元,我猜想STA应该是Single Thread Apartment的首字母简拼;MTA:表示Thread将被创建并进入一个多线程单元,还有一个是Unknown,表示没有设置线程的单元状态。我在以前使用Thread的时候,从来没有设置过线程的单元状态,今天要做个试验把这三种状态搞清楚。

 

使用新new 一个Thread实例之后可以使用SetAppartmentState方法设置线程的单元状态,每个线程只可以设置一次,若再次设置会抛异常,若不知道是否设置了单元状态可以使用Thread类提供的TrySetApartmentState方法来设置;不设置时其线程单元在控制台应用程序中默认是MTA。

 

试验思路:
1. 使用new 3个Thread的实例,什么都不执行,看两种不同的AppartmentState的Thread的执行顺序如何
2. 同样new 3个Thread实例,执行一段计算代码,看两种不同的AppartmentState执行完全部计算耗时情况

 

具体的实验代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.Collections;

namespace MutiThread
{
    class Program
    {
        static Stopwatch swAll;
        static Random r = new Random();
        static Hashtable hashTable;
        

        static void Main(string[] args)
        {
            Start3Thread(ApartmentState.STA);

            Console.ReadLine();
        }

        static void Start3Thread(ApartmentState appartmentState)
        {
            int threadCn = 3;
            hashTable = new Hashtable();
            swAll = new Stopwatch();
            swAll.Start();

            do
            {
                StartThread(appartmentState);
                threadCn--;
            } while (threadCn > 0);
        }

        static void StartThread(ApartmentState appartmentState)
        {
            Thread t1 = new Thread(new ThreadStart(CalcSomething));
            
            //Thread t1 = new Thread(new ThreadStart(DoNothing));
            hashTable.Add(t1.ManagedThreadId, false);
            t1.SetApartmentState(appartmentState);
            t1.Start();
        }



        static void CalcSomething()
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            int[] arr = new int[1000];
            for (int i = 0; i < arr.Length; i++)
            {
                arr[i] = r.Next(1000);
            }
            //Console.WriteLine("线程" + Thread.CurrentThread.ManagedThreadId
            //        + "的单元状态是:" + Thread.CurrentThread.GetApartmentState()
            //        + ";线程状态:" + Thread.CurrentThread.ThreadState
            //        + ";耗时:" + sw.ElapsedTicks);
            hashTable[Thread.CurrentThread.ManagedThreadId] = true;
            
            if (hashTable.Count == 3)
            {
                bool allFinish = true;
                foreach (object key in hashTable.Keys)
                {
                    allFinish = allFinish && (bool)hashTable[key];
                }
                if (allFinish)
                {
                    swAll.Stop();
                    Console.WriteLine(Thread.CurrentThread.GetApartmentState().ToString() + "总耗时:" + swAll.ElapsedTicks);
                    if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
                    {
                        hashTable.Clear();
                        swAll.Reset();
                        swAll.Start();
                        Start3Thread(ApartmentState.MTA);
                    }
                }
            }
        }

        static void DoNothing()
        {
            int times = 3;
            do
            {
                Console.WriteLine("线程" + Thread.CurrentThread.ManagedThreadId
                    + "的单元状态是:" + Thread.CurrentThread.GetApartmentState()
                    + ";线程状态:" + Thread.CurrentThread.ThreadState);
                times--;
            } while (times > 0);
        }
    }
}

 

 

实验的结果是:
1. AppartmentState为STA或者MTA时的执行顺序都是不定的,每一次执行都可能不同,也就是说顺序上无法说明两种的区别。
2. 两种不同的ApartmentState的执行效率上是有区别的,单线程单元状态模式所耗时间明显多于多线程单元模式状态
3. 在不设置线程的AppartmentState时,默认值是MTA,也就是多线程模式的

 

我的测试CPU是单CPU的,具体如下:
Intel(R)Pentium(R)4CPU
3.00GHz
2.99GHz,1.99GB的内存

 

2
0
分享到:
评论

相关推荐

    .Net 3.5 使用 System.Threading.Task

    .Net 3.5 下使用的 System.Threading.Tasks。 安装完成后,添加引用时只需要在安装目录 C:\Program Files (x86)\Microsoft Reactive Extensions\Redist\DesktopV2 下找到 System.Threading.dll,添加即可

    system.Threading.Timer的使用

    在.NET框架中,`System.Threading.Timer`类是一个用于在后台线程上执行周期性操作的强大工具。这个类属于多线程编程的一部分,特别是在处理异步任务和定时触发事件时非常有用。下面我们将深入探讨`System.Threading....

    .NET Framework 3.5上使用System.Threading.Tasks

    我在做一个兼容WindowsXP项目时用到,用梯子到外面找来的。 由于 .NET 3.5下并没有官方实现的 Task 库,所以,是通过 VS 中 NuGet 取得的 非官方 实现的 Task 库,调用接口与官方.NET 4.0 后的应该是差不多的。

    System.Threading.zip

    .Net 3.5支持Plinq的相关信息已被微软撤掉了, 而引用此dll可以使3.5的Linq支持AsParallel()方法, 3.5可以使用1.0.3058.34407版本。...using System.Threading.Tasks; using System.Threading; using System.Linq;

    Thread类位于System.Threading命名空间下,System.Threading命名空间提供一些可以进行多线程

    在C#编程中,`System.Threading`命名空间是多线程编程的核心,它提供了大量类和接口用于创建、管理和同步线程。`Thread`类是这个命名空间中的关键类,它代表了一个执行线程,允许程序员直接控制线程的生命周期。在`...

    C#中Forms.Timer、Timers.Timer、Threading.Timer的用法分析

    本文实例讲述了C#中Forms.Timer、Timers.Timer、Threading.Timer的用法...1、基于Windows消息循环,用事件方式触发,在界面线程执行;是使用得比较多的Timer,Timer Start之后定时(按设定的Interval)调用挂接在Tick事

    Python库 | click_threading-0.5.0-py2.py3-none-any.whl

    `click_threading` 是一个基于Python的库,用于在命令行接口(CLI)应用程序中集成多线程功能。这个库是为了解决一个问题,即如何在使用`click`库创建的命令行工具中轻松地利用多线程来提高程序执行效率。`click`是...

    Python内置库:threading(多线程操作).docx

    - `threading.current_thread()`: 获取当前运行的线程对象,如果是非`threading.Thread`创建的线程,将返回一个受限的虚拟线程对象。 - `threading.get_ident()`: 获取当前线程的唯一标识符,这个标识符可能在线程...

    dxperience9.1官方汉化

    System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CN"); System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("zh-...

    C# WPf经典教程包含有14个文件

    • System.Windows.Threading.DispatcherObject类:WPF 中的大多数对象是从 DispatcherObject 派生的,这提供了用于处理并发和线程的基本构造。WPF 基于调度程序实现的消息系统。 • System.Windows....

    C#利用System.Threading.Thread.Sleep即时输出信息的详解

    在C#编程中,`System.Threading.Thread.Sleep`是一个非常有用的函数,它允许当前线程暂停执行指定的时间量,以便让其他线程有机会运行。在本文中,我们将深入探讨如何利用`Thread.Sleep`来实现即时输出信息,特别是...

    C#常用的42个类

    10. `System.Threading.Thread`:线程类,用于多线程编程。 11. `System.Threading.Tasks.Task`:任务类,支持异步编程,是.NET 4.0及以后版本的推荐方式。 12. `System.DateTime`:日期时间类,处理日期和时间...

    [翻译中文]4本iOS开发Apple官方原版教材-Core Animation.....

    多线程编程指南.pdf------ (Apple官方原版:Threading Programming Guide.pdf) Instruments 用户指南.pdf------ (Apple官方原版:Instruments User Guide.pdf) Blocks 编程要点.pdf------ (Apple官方原版:Blocks ...

    System.Diagnostics.Process的简单包装器,将其公开为System.Threading.Tasks.zip

    标题中的"System.Diagnostics.Process的简单包装器,将其公开为System.Threading.Tasks"暗示了一个关于.NET框架中的两个关键组件的讨论:`System.Diagnostics.Process`类和`System.Threading.Tasks`命名空间。...

    C#多线程系列讲座(同步,死锁等知识)

    在C#中,可以使用`System.Threading`命名空间中的`Thread`类来创建和管理线程。 1. **线程的创建与启动**:在C#中,可以通过实例化`Thread`类并传递一个委托(代表线程执行的代码)来创建新线程。然后调用`Start()`...

    C sharp 中常用的42个类

    14. **System.Threading.Thread**:线程类,支持多线程编程。 15. **System.Threading.Tasks.Task**:异步任务类,用于实现异步编程。 16. **System.Net.HttpClient**:网络请求类,支持HTTP/HTTPS请求。 17. **...

Global site tag (gtag.js) - Google Analytics