併發編程技術之一 ———— 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!!!
相關文章
相關標籤/搜索