C#知識系列
程序:一個程式執行起來所占用的全部計算資源總合。
關於執行緒:
- 程序執行的最小單位
- 任何操作都由執行緒完成
- 是依賴在程序存在,一個程序可以包含很多執行緒,有自己的計算資源
- 系統分配的CPU時間基本單位,程序第一個執行緒,為主執行緒
多執行緒:是實現執行緒並發執行的技術。
多執行緒優點:同時完成多個job,可以讓占用大量時間的任務或當前
沒進行的任務定期處理讓給別的任務,可以隨時停止
任務,可設定每個job的優先級,優化程式效能
多執行緒缺點:
1、 内存占用: 執行緒需要佔用內存,執行緒越多,占用内存也越多(每個執行
緒都需要建立堆疊空間,多執行緒有時需要切換時間片)。
2、 管理協調:多執行緒需要協調和管理,所以需要占用CPU時間以便追蹤執行緒,
執行緒太多會導致控制太複雜。
3、 資源共享:執行緒之間對共享資源會相互影響,必須解決共享資源問題。
關於C#多執行緒,EX:Thread是C#語言對執行緒的封裝。
同步方法:計算完成處理後,進入下一行。
EX:如果eddie要邀請阿龍去吃飯,但是阿龍要忙,那就要等阿龍完成再一起去吃飯。
非同步方法:只發送請求處理,不會等待處理完成,進入下一行,非阻塞。
EX:如果eddie要邀請阿龍去吃飯,但是阿龍要忙,eddie先去吃飯,阿龍忙完了自己去吃飯。
非同步多執行緒:thread pool task
以下是多執行緒和非同步的狀況
接者來看畫面和程式
先設定專案啟用主控台
畫面
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 同步方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSync_Click(object sender, EventArgs e)
{
Console.WriteLine($"****************btnSync_Click Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
for (int i = 0; i < 5; i++)
{
string name = string.Format($"btnSync_Click_{i}");
this.DoSomethingLong(name);
}
Console.WriteLine($"****************btnSync_Click End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
}
/// <summary>
/// 異步方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnAsync_Click(object sender, EventArgs e)
{
Console.WriteLine("");
Console.WriteLine($"****************btnAsync_Click Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
Action<string> action = this.DoSomethingLong;
//for (int i = 0; i < 5; i++)
//{
// string name = string.Format($"btnAsync_Click_{i}");
// action.BeginInvoke(name, null, null);
//}
action.Invoke("btnAsync_Click_1");
action("btnAsync_Click_2");
//非同步多執行緒
action.BeginInvoke("btnAsync_Click_3", null, null);
Console.WriteLine($"****************btnAsync_Click End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
}
private void DoSomethingLong(string name)
{
Console.WriteLine($"****************DoSomethingLong Start {name} {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
long lResult = 0;
for (int i = 0; i < 100000000; i++)
{
lResult += i;
}
Thread.Sleep(2000);
Console.WriteLine($"****************DoSomethingLong End {name} {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} {lResult}***************");
}
}
當你在運行同步方法的時候,就會UI卡死,執行btnSync_Click就會卡死概念。
同步事件:主執行緒(UI部分),忙者計算、畫面卡死
非同步的話就不一樣嚕
非同步:主要執行緒丟任務給子執行緒完成,改善用戶體驗,不至於卡死,例如大量EMAIL寄信通知,就可以給非同步去做。
同步方法比較慢,因為只有一個執行緒計算,異步方法快,可以用多個執
行緒併發計算,多執行緒就是用資源來換效能。
多執行緒使用時機:
查詢DB或讀取硬碟文件或數據計算,可以用多執行緒下效能優化?
A:可以、因為多任務可以並行,但是多執行緒不是越多越好,因為資源有限,調度有消耗,多執行緒盡量避免使用
接者微調程式來看一下檢視程式結果
private void btnAsync_Click(object sender, EventArgs e)
{
Console.WriteLine("");
Console.WriteLine($"****************btnAsync_Click Start {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
Action<string> action = this.DoSomethingLong;
for (int i = 0; i < 5; i++)
{
string name = string.Format($"btnAsync_Click_{i}");
action.BeginInvoke(name, null, null);
}
Console.WriteLine($"****************btnAsync_Click End {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
}
接者我們在迴圈加個0,來實驗CPU的效果和成效
private void DoSomethingLong(string name)
{
Console.WriteLine($"****************DoSomethingLong Start {name} {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}***************");
long lResult = 0;
//修改前100000000
for (int i = 0; i < 1000000000; i++)
{
lResult += i;
}
Thread.Sleep(2000);
Console.WriteLine($"****************DoSomethingLong End {name} {Thread.CurrentThread.ManagedThreadId.ToString("00")} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} {lResult}***************");
}
從上圖來看同步方法的秒數消耗十幾秒、CPU曲線調用性是屬於穩定的
如果是下圖是非同步的話
那CPU的曲線就會過高,異步就會用資源來換取速度
同步方法慢、只有一個執行緒執行處理,異步方法快,因為資源換時間,但是資源可
能會不夠,多執行緒也有管理成本不是開越多越好,必須多個獨立任務可以同時運行。
從上圖和下圖來看,下圖五個同時調用,啟動的時候在跟OS調用資源時候,它是無序(啟動/結束),執行時間不確定
元哥的筆記