[深入學習C#]C#實現多執行緒的方法:執行緒(Thread類)和執行緒池(ThreadPool)
簡介
使用執行緒的主要原因:應用程式中一些操作需要消耗一定的時間,比如對檔案、資料庫、網路的訪問等等,而我們不希望使用者一直等待到操作結束,而是在此同時可以進行一些其他的操作。
這就可以使用執行緒來實現。
本文主要介紹關於Thread和ThreadPool的基礎知識。
Thread類
基本用法
使用Thread類可以建立和控制執行緒,在下面的示例程式碼中,Thread類的建構函式過載為接受ThreadStart和ParameterizedThreadStart型別的委託引數。ThreadStart委託定義了一個返回型別為void的無引數方法,在建立Thread物件後,就可以用Start()方法啟動執行緒。
using System;
using System.Threading;
namespace ThreadDemo
{
class Program
{
static void Main()
{
var t1 = new Thread(ThreadMain);
t1.Start();
Console.WriteLine("This is the main thread.");
}
static void ThreadMain()
{
Console.WriteLine("Running in a thread.");
}
}
}
程式執行結果,得到兩個執行緒的輸出:
This is the main thread.
Running in a thread.
我們知道,我們並不能保證那個結果先輸出,這由作業系統排程決定。
在前文中,我們探討了將Lambda表示式和非同步委託結合使用,這裡我們也使用Lambda表示式與來給Thread類建構函式傳遞引數:
using System.Threading;
namespace ThreadDemo
{
class Program
{
static void Main()
{
var t1 = new Thread(()=>Console.WriteLine("Running in a thread, id : {0}",Thread.CurrentThread.ManagedThreadId));
t1.Start();
Console.WriteLine("This is the main thread, id : {0}",Thread.CurrentThread.ManagedThreadId);
}
}
}
在應用程式的輸出中,我們可以看到執行緒id,當然,每次執行的結果不一定一樣,因為系統每次分配的執行緒是獨立的。
This is the main thread, id : 1.
Running in a thread, id : 3.
給執行緒傳遞資料
前面的例子中,我們開啟的新執行緒只是執行了一個簡單的輸出指令,並沒有執行緒中的方法賦予引數。現在我們來探討如何給執行緒傳遞引數,也就是傳遞資料。
一種方式是使用帶ParameterizedThreadStart委託引數的Thread建構函式;
另一種方法是將自定義的方法傳遞給執行緒,然後啟動執行緒。
● 方法一:使用ParameterizedThreadStart委託。
該委託的例項方法必須帶有一個object引數,而且返回型別為void。
假設該委託例項方法如下:
static void ThreadMainWithParameters(object o)
{
...
...
}
那麼我可以這樣開啟執行緒:
var o = new object();
var t1 = new Thread(ThreadMainWithParameters);
t1.Start(o);
● 方法二:使用自定義方法。
假設我們有一個MyThread類,該類有一個方法ThreaMain():
public class MyThread
{
...
...
public void ThreadMain()
{
...
...
}
...
...
}
開啟執行緒方法如下:
var o = new MyThread();
var t1 =new Thread(o.ThreadMain);
t1.Start();
執行緒池
我們知道,執行緒的建立需要時間。 如果有不同的小任務要完成,我們就可以事先建立許多執行緒, 在應完成這些任務時發出請求。 這個執行緒數最好在需要更多的執行緒時增加,在需要釋放資源時減少。
這些執行緒就是放線上程池中,C#為我們提供了一個管理執行緒池的類:ThreadPool。
它會在需要的時候增減執行緒池中的執行緒數,如果執行緒池中執行緒數到達上限,新的作業就需要排隊等待其他執行緒完成其任務。
下面的示例應用程式首先要讀取工作執行緒和 I/O執行緒的最大執行緒數,把這些資訊寫入控制檯中。接著在for迴圈中,呼叫 ThreadPool.QueueUserWorkItem()方法,傳遞一個WaitCallBack型別的委託,把 JobForThread()方法賦予執行緒池中的執行緒。執行緒池收到這個請求後,就會從池中選擇一個執行緒,來呼叫該方法。 如果執行緒池還沒有執行,就會建立一個執行緒池,並啟動第一個執行緒。 如果執行緒池己經在執行,且有一個空閒執行緒來完成該任務,就把該作業傳遞給這個執行緒。
using System;
using System.Threading;
namespace ThreadDemo
{
class program
{
static void Main()
{
int nWorkThreads;
int nCompletionPortThreads;
ThreadPool.GetMaxThreads(out nWorkThreads, out nCompletionPortThreads);
Console.WriteLine("Max worker threads: {0}, I/O completion threads: {1}",nWorkThreads, nCompletionProtThreads);
for(int i = 0; i < 5; i++)
{
ThreadPool.QueueUserWorkItem(JobForAThread);
}
Thread.Sleep(3000);
}
static void JobForAThread(object state)
{
for(int i = 0; i < 3; i++)
{
Console.WriteLine("loop {0}, running inside pooled thread {1}", i, Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(50);
}
}
}
}
讀者執行該程式的結果可能與此不同,也可以改變作業的睡眠時間和要處理的作業數,得到完全不同的結果。
執行緒池使用起來很簡單,但它有一些限制 :
● 執行緒池中的所有執行緒都是後臺執行緒 。 如果程式的所有前臺執行緒都結束了,所有的後臺執行緒就會停止。 不能把入池的執行緒改為前臺執行緒 。
● 不能給入池的執行緒設定優先順序或名稱。
● 對於 COM對 象,入池的所有執行緒都是多執行緒單元(multit-threaded apartment , MTA)執行緒。 許 COM物件都需要單執行緒單元(single-threaded apartment , STA)線 程。
● 入池的執行緒只能用於時間較短的任務。 如果執行緒要一直執行(如Word的拼寫檢查器執行緒),就應使用Thread類建立一個執行緒。
相關文章
- C#多執行緒開發-執行緒池03C#執行緒
- ThreadPool執行緒池thread執行緒
- C#多執行緒(6):執行緒通知C#執行緒
- 多執行緒【執行緒池】執行緒
- 執行緒和執行緒池執行緒
- 深入淺出Java多執行緒(十二):執行緒池Java執行緒
- C#多執行緒開發-執行緒同步 02C#執行緒
- C#多執行緒學習(二) 如何操縱一個執行緒C#執行緒
- SpringBoot執行緒池和Java執行緒池的實現原理Spring Boot執行緒Java
- Android多執行緒之執行緒池Android執行緒
- kuangshenshuo-多執行緒-執行緒池執行緒
- 多執行緒之手撕執行緒池執行緒
- java多執行緒9:執行緒池Java執行緒
- Java多執行緒-執行緒池的使用Java執行緒
- C#多執行緒開發-執行緒基礎 01C#執行緒
- 深入學習執行緒池原理執行緒
- C#多執行緒程式設計實戰1.1建立執行緒C#執行緒程式設計
- C# 多執行緒猜想C#執行緒
- Java多執行緒學習(八)執行緒池與Executor 框架Java執行緒框架
- 多執行緒:執行緒池理解和使用總結執行緒
- 【Java】【多執行緒】執行緒池簡述Java執行緒
- 執行緒 執行緒池 Task執行緒
- 手寫執行緒池,對照學習ThreadPoolExecutor執行緒池實現原理!執行緒thread
- 多執行緒和多執行緒同步執行緒
- java多執行緒之Thread類Java執行緒thread
- Java多執行緒(二):Thread類Java執行緒thread
- Java多執行緒Thread類使用Java執行緒thread
- c# 執行緒Thread的IsBackground屬性C#執行緒thread
- Java核心(二)深入理解執行緒池ThreadPoolJava執行緒thread
- 執行緒、多執行緒和執行緒池,看完這些你就能全部搞懂了執行緒
- 執行緒池學習執行緒
- 多執行緒學習一(多執行緒基礎)執行緒
- 多執行緒(五)---執行緒的Yield方法執行緒
- Java多執行緒學習(3)執行緒同步與執行緒通訊Java執行緒
- Java多執行緒學習——執行緒通訊Java執行緒
- Java多執行緒學習(2)執行緒控制Java執行緒
- c#基礎,單執行緒,跨執行緒訪問和執行緒帶引數C#執行緒
- C# 多執行緒學習筆記 – 1C#執行緒筆記
- 多執行緒系列(三):執行緒池基礎執行緒