文章目錄
- IO密集型與CPU密集型任務詳解(C#示例)
- 一、基本概念
- 1. IO密集型任務
- 2. CPU密集型任務
- 二、C#示例
- 1. IO密集型示例
- 1.1 文件操作異步示例
- 1.2 網絡請求異步示例
- 1.3 數據庫操作異步示例
- 2. CPU密集型示例
- 2.1 基本CPU密集型異步處理
- 2.2 并行處理CPU密集型任務
- 2.3 進度報告和取消支持
- 三、處理策略
- 1. IO密集型任務優化
- 2. CPU密集型任務優化
- 混合示例(并行處理CPU密集型任務)
- 四、總結
IO密集型與CPU密集型任務詳解(C#示例)
一、基本概念
1. IO密集型任務
IO密集型任務(Input/Output Bound)是指執行過程中大部分時間都在等待輸入/輸出操作完成的任務。這些任務的特點是CPU計算量相對較小,主要時間花費在磁盤讀寫、網絡通信、數據庫訪問等IO操作上。
特點:
- CPU利用率通常較低
- 性能瓶頸主要在IO設備速度
- 可通過異步編程或增加IO帶寬來提高性能
2. CPU密集型任務
CPU密集型任務(CPU Bound)是指需要大量計算處理的任務,執行時間主要消耗在CPU計算上,而不是等待IO操作。
特點:
- CPU利用率高(接近100%)
- 性能瓶頸主要在CPU處理能力
- 可通過優化算法或增加CPU核心數來提高性能
二、C#示例
1. IO密集型示例
1.1 文件操作異步示例
using System;
using System.IO;
using System.Threading.Tasks;class Program
{static async Task ProcessFileAsync(){string filePath = "data.txt";try{// 異步寫入文件Console.WriteLine("開始寫入文件...");await File.WriteAllTextAsync(filePath, "這是異步寫入的內容");Console.WriteLine("文件寫入完成");// 異步讀取文件Console.WriteLine("開始讀取文件...");string content = await File.ReadAllTextAsync(filePath);Console.WriteLine($"文件內容: {content}");// 異步追加內容Console.WriteLine("開始追加內容...");await File.AppendAllTextAsync(filePath, "\n這是追加的內容");Console.WriteLine("內容追加完成");}catch (Exception ex){Console.WriteLine($"發生錯誤: {ex.Message}");}}static async Task Main(string[] args){await ProcessFileAsync();}
}
1.2 網絡請求異步示例
using System;
using System.Net.Http;
using System.Threading.Tasks;class Program
{static async Task FetchDataAsync(){using var client = new HttpClient();try{// 異步GET請求Console.WriteLine("開始請求數據...");string response = await client.GetStringAsync("https://api.example.com/data");Console.WriteLine($"獲取數據成功,長度: {response.Length}");// 異步POST請求var content = new StringContent("{\"name\":\"value\"}", System.Text.Encoding.UTF8, "application/json");Console.WriteLine("開始提交數據...");var responseMsg = await client.PostAsync("https://api.example.com/submit", content);Console.WriteLine($"提交數據完成,狀態碼: {responseMsg.StatusCode}");}catch (HttpRequestException ex){Console.WriteLine($"網絡請求錯誤: {ex.Message}");}}static async Task Main(string[] args){await FetchDataAsync();}
}
1.3 數據庫操作異步示例
using System;
using System.Data.SqlClient;
using System.Threading.Tasks;class Program
{static async Task QueryDatabaseAsync(){string connectionString = "Server=.;Database=TestDB;Integrated Security=True;";using var connection = new SqlConnection(connectionString);await connection.OpenAsync();// 異步查詢using var command = new SqlCommand("SELECT * FROM Users WHERE Age > @age", connection);command.Parameters.AddWithValue("@age", 20);Console.WriteLine("開始數據庫查詢...");using var reader = await command.ExecuteReaderAsync();while (await reader.ReadAsync()){Console.WriteLine($"用戶: {reader["Name"]}, 年齡: {reader["Age"]}");}Console.WriteLine("查詢完成");}static async Task Main(string[] args){await QueryDatabaseAsync();}
}
2. CPU密集型示例
2.1 基本CPU密集型異步處理
using System;
using System.Threading.Tasks;class Program
{static int CalculatePrimes(int max){int count = 0;for (int i = 2; i <= max; i++){if (IsPrime(i)) count++;}return count;}static bool IsPrime(int number){if (number <= 1) return false;if (number == 2) return true;if (number % 2 == 0) return false;var boundary = (int)Math.Floor(Math.Sqrt(number));for (int i = 3; i <= boundary; i += 2){if (number % i == 0) return false;}return true;}static async Task Main(string[] args){Console.WriteLine("主線程開始");// 將CPU密集型任務放到后臺線程var primeTask = Task.Run(() => CalculatePrimes(1000000));// 主線程可以繼續做其他工作Console.WriteLine("主線程繼續執行其他工作...");await Task.Delay(500); // 模擬其他工作// 等待計算結果int result = await primeTask;Console.WriteLine($"計算完成,素數數量: {result}");}
}
2.2 并行處理CPU密集型任務
using System;
using System.Linq;
using System.Threading.Tasks;class Program
{static bool IsPrime(int number){// 同上省略...}static async Task<int> ParallelCountPrimesAsync(int max, int partitions){// 分割工作范圍var ranges = Enumerable.Range(0, partitions).Select(i => (start: i * (max / partitions) + 1, end: (i == partitions - 1) ? max : (i + 1) * (max / partitions))).ToList();// 并行執行任務var tasks = ranges.Select(range => Task.Run(() =>{int count = 0;for (int num = range.start; num <= range.end; num++){if (IsPrime(num)) count++;}return count;}));// 等待所有任務完成并匯總結果var results = await Task.WhenAll(tasks);return results.Sum();}static async Task Main(string[] args){Console.WriteLine("開始并行計算...");int result = await ParallelCountPrimesAsync(1000000, 4);Console.WriteLine($"計算完成,素數數量: {result}");}
}
2.3 進度報告和取消支持
using System;
using System.Threading;
using System.Threading.Tasks;class Program
{static async Task LongRunningCpuTaskAsync(IProgress<int> progress, CancellationToken cancellationToken){for (int i = 0; i <= 100; i++){// 檢查是否取消cancellationToken.ThrowIfCancellationRequested();// 模擬CPU密集型工作await Task.Run(() => {// 模擬計算for (int j = 0; j < 1000000; j++){var _ = Math.Sqrt(j);}});// 報告進度progress?.Report(i);}}static async Task Main(string[] args){var progress = new Progress<int>(percent => Console.WriteLine($"進度: {percent}%"));var cts = new CancellationTokenSource();// 設置5秒后取消cts.CancelAfter(5000);try{Console.WriteLine("開始長時間CPU任務...");await LongRunningCpuTaskAsync(progress, cts.Token);Console.WriteLine("任務完成");}catch (OperationCanceledException){Console.WriteLine("任務已取消");}}
}
三、處理策略
1. IO密集型任務優化
- 使用異步編程模型(async/await)
- 增加IO帶寬(更快磁盤、網絡)
- 批量處理減少IO次數
- 使用緩存減少IO操作
2. CPU密集型任務優化
- 多線程/并行處理(Parallel類、Task.Run)
- 優化算法復雜度
- 使用更高效的庫(如Math.NET Numerics)
- 使用SIMD指令(Vector)
混合示例(并行處理CPU密集型任務)
using System;
using System.Threading.Tasks;class Program
{static bool IsPrime(int number){// 同上省略...}static async Task Main(string[] args){// 并行計算素數(CPU密集型)int max = 1000000;int segmentSize = max / 4;var tasks = new Task<int>[4];for (int i = 0; i < 4; i++){int start = i * segmentSize + 1;int end = (i == 3) ? max : (i + 1) * segmentSize;tasks[i] = Task.Run(() => {int count = 0;for (int num = start; num <= end; num++){if (IsPrime(num)) count++;}return count;});}await Task.WhenAll(tasks);int totalPrimes = 0;foreach (var task in tasks){totalPrimes += task.Result;}Console.WriteLine($"并行計算100萬以內素數總數: {totalPrimes}");}
}
using System;
using System.IO;
using System.Threading.Tasks;class Program
{static async Task ProcessDataAsync(string inputFile, string outputFile){// IO密集型:異步讀取文件Console.WriteLine("開始讀取文件...");string content = await File.ReadAllTextAsync(inputFile);// CPU密集型:處理數據(轉移到后臺線程)Console.WriteLine("開始處理數據...");string processedContent = await Task.Run(() => ProcessContent(content));// IO密集型:異步寫入結果Console.WriteLine("開始寫入結果...");await File.WriteAllTextAsync(outputFile, processedContent);Console.WriteLine("處理完成");}static string ProcessContent(string content){// 模擬CPU密集型處理var charArray = content.ToCharArray();for (int i = 0; i < charArray.Length; i++){if (i % 2 == 0){charArray[i] = char.ToUpper(charArray[i]);}else{charArray[i] = char.ToLower(charArray[i]);}}return new string(charArray);}static async Task Main(string[] args){await ProcessDataAsync("input.txt", "output.txt");}
}
四、總結
- IO密集型:主要時間花費在等待IO操作,應關注IO優化和異步編程
- CPU密集型:主要時間花費在計算,應關注算法優化和多核利用
- 實際應用:很多任務是混合型的,需要根據瓶頸采取相應策略
- C#特性:充分利用async/await、Task、Parallel等特性處理不同類型任務