并发编程技术之一 ———— C#多线程基础

1. C#多线程技术简介

线程是一个独立的运行单元,每一个进程内部有多个线程,每一个线程能够各自同时执行指令。每一个线程有本身独立的栈,可是与进程内的其余线程共享内存。对某些程序来讲,其中有一个线程是特殊的,例如:Console的main线程和窗体程序的UI线程。git

每一个.NET程序都有一个线程池,线程池维护着必定数量的工做线程,这些线程等待着执行分配下来的任务,线程池能够随时监测线程的数量。配置线程池的参数不少。可是我都建议你们使用默认值,这些值都是通过微软调试好的,能够知足大部分应用。github

线程是低级别的抽象,线程池虽然高级一点,但一样很低,而如今C#给咱们提供了不少高级的并发编程技术工具,因此原则上咱们不建议直接操做 Thread对象。可是为了让你们很好的理解C#多线程的前因后果,这里介绍C#最初操做多线程的方法。

2 实战:第一个程序

因为写博客我喜欢用Mac,因此个人例程是用.net core 框架,使用 VS Code 开发,源码发布到github中,连接:spartajet/CSharpLearnBlog编程

2.1 C# 建立线程

首先,咱们要建立一个新建线程中运行的方法,主要是打印数字,以下:c#

/// <summary>
/// 数数方法
/// </summary>
static void NumberCount(){
for (int i = 0; i < 10; i++)
    {
        Console.WriteLine($"The number is {i}");
    }
}

main方法中添加以下代码来开启一个线程多线程

static void Main(string[] args)
{
    Thread workThread=new Thread(NumberCount);
    workThread.Start();
    NumberCount();
}

运行结果,以下:并发

The number is 0
The number is 0
The number is 1
The number is 2
The number is 3
The number is 4
The number is 5
The number is 6
The number is 7
The number is 8
The number is 9
The number is 1
The number is 2
The number is 3
The number is 4
The number is 5
The number is 6
The number is 7
The number is 8
The number is 9

能够看出,C#的多线程执行顺序是不肯定的。NumberCount方法同时被工做线程和主线程调用,能够看到工做线程和主线程是同步运行的,互不干扰。框架

Thread的声明还有其余方式,可使用Lambda风格来定义。方法以下:工具

var workThread=new Thread(() =>
{
    for (int i = 0; i < 10; i++)
    {
        Console.WriteLine($"The number is {i}");
    }
});

2.2 暂停一个线程

暂停一个线程是让一个线程等待一段时间而不消耗操做系统资源。 测试

将方法NumberCount 修改成:this

/// <summary>
/// 数数方法
/// </summary>
static void NumberCountCouldDelay(){
for (int i = 0; i < 10; i++)
    {
        Console.WriteLine($"The number is {i}");
        Thread.Sleep(TimeSpan.FromSeconds(1));
    }
}

运行结果为:

The number is 0
The number is 0
The number is 1
The number is 1
The number is 2
The number is 2
The number is 3
The number is 3
The number is 4
The number is 4
The number is 5
The number is 5
The number is 6
The number is 6
The number is 7
The number is 7
The number is 8
The number is 8
The number is 9
The number is 9

你们能够看到,方法改动只是增长了一行

Thread.Sleep(TimeSpan.FromSeconds(1));

Thread.Sleep 方法被调用后,线程处于休眠状态,会尽量的少占用系统资源,起到了暂停线程的效果。

2.3 线程等待

线程等待是指多线程编程中,一个线程等待另外一个线程完成后再执行。

代码以下:

static void Main(string[] args)
{
    var workThread=new Thread(NumberCountCoudDelay);
    workThread.Start();
    workThread.Join();
    NumberCount();
}
/// <summary>
/// 数数方法
/// </summary>
static void NumberCountCoudDelay(){
    for (int i = 0; i < 10; i++)
    {
        Console.WriteLine($"Delay thread number is {i}");
        Thread.Sleep(TimeSpan.FromSeconds(1));
    }
}
/// <summary>
/// 数数方法
/// </summary>
static void NumberCount(){
    for (int i = 0; i < 10; i++)
    {
        Console.WriteLine($"Main thread number is {i}");
        Thread.Sleep(TimeSpan.FromSeconds(1));
    }
}

运行结果:

Delay thread number is 0
Delay thread number is 1
Delay thread number is 2
Delay thread number is 3
Delay thread number is 4
Delay thread number is 5
Delay thread number is 6
Delay thread number is 7
Delay thread number is 8
Delay thread number is 9
Main thread number is 0
Main thread number is 1
Main thread number is 2
Main thread number is 3
Main thread number is 4
Main thread number is 5
Main thread number is 6
Main thread number is 7
Main thread number is 8
Main thread number is 9

能够看出来,咱们使用了 Join 方法,该方法容许咱们等待知道此线程完成,当线程完成后,下面的代码才能够执行。

2.4 结束线程

结束线程是指在某个线程运行中间中止该线程。

代码以下:

static void Main(string[] args)
{
    var workThread=new Thread(NumberCountCoudDelay);
    workThread.Start();
    Thread.Sleep(TimeSpan.FromSeconds(4));
    workThread.Abort();
    Console.WriteLine("Work thread is stopped!!!");
}

结果以下:

Delay thread number is 0
Delay thread number is 1
Delay thread number is 2
Delay thread number is 3

Unhandled Exception: Delay thread number is 4
System.PlatformNotSupportedException: Thread abort is not supported on this platform.
   at System.Threading.Thread.Abort()
   at CSharpAsync.Program.Main(String[] args) in /Users/spartajet/CodeWorkSpace/VSCode/CSharpLearnBlog/CSharpAsync/Program.cs:line 12

为何会出现这个现象呢,请参照:Methods that throw PlatformNotSupportedException are not documented

能够看出.net coreThread 的支持不够,是由于 Thread 已经彻底落伍了,一样在Windows咱们也不建议这么作。
方法代码以下:

public void Abort()
    {
      throw new PlatformNotSupportedException(SR.PlatformNotSupported_ThreadAbort);
    }

    public void Abort(object stateInfo)
    {
      throw new PlatformNotSupportedException(SR.PlatformNotSupported_ThreadAbort);
    }

    public static void ResetAbort()
    {
      throw new PlatformNotSupportedException(SR.PlatformNotSupported_ThreadAbort);
    }

    [Obsolete("Thread.Suspend has been deprecated.  Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources.  http://go.microsoft.com/fwlink/?linkid=14202", false)]
    public void Suspend()
    {
      throw new PlatformNotSupportedException(SR.PlatformNotSupported_ThreadSuspend);
    }

可是在Windows平台这段代码是彻底可行的。

2.5 检测线程状态

一个线程能够用 ThreadState 枚举来表示,

下面是ThreadState的源码:

public enum ThreadState
{
  Running = 0,
  StopRequested = 1,
  SuspendRequested = 2,
  Background = 4,
  Unstarted = 8,
  Stopped = 16, // 0x00000010
  WaitSleepJoin = 32, // 0x00000020
  Suspended = 64, // 0x00000040
  AbortRequested = 128, // 0x00000080
  Aborted = 256, // 0x00000100
}

测试代码以下:

static void Main(string[] args)
{
    var workThread=new Thread(NumberCountCoudDelay);
    Console.WriteLine($"work thread state: {workThread.ThreadState}");
    workThread.Start();
    workThread.Join();
    Console.WriteLine($"work thread state: {workThread.ThreadState}");
    Console.WriteLine("Work thread is stopped!!!");
}

结果以下:

work thread state: Unstarted
Delay thread number is 0
work thread state: Running
Delay thread number is 1
work thread state: Running
Delay thread number is 2
work thread state: Running
Delay thread number is 3
work thread state: Running
Delay thread number is 4
work thread state: Running
Delay thread number is 5
work thread state: Running
Delay thread number is 6
work thread state: Running
Delay thread number is 7
work thread state: Running
Delay thread number is 8
work thread state: Running
Delay thread number is 9
work thread state: Running
work thread state: Stopped
Work thread is stopped!!!
相关文章
相关标签/搜索