C#多线程举例分析

发布时间:2021-12-13 11:05:09 作者:iii
来源:亿速云 阅读:205
# C#多线程举例分析

## 目录
1. [多线程基础概念](#一多线程基础概念)
   - 1.1 [进程与线程的区别](#11-进程与线程的区别)
   - 1.2 [多线程的应用场景](#12-多线程的应用场景)
2. [C#多线程实现方式](#二c多线程实现方式)
   - 2.1 [Thread类](#21-thread类)
   - 2.2 [ThreadPool](#22-threadpool)
   - 2.3 [Task](#23-task)
   - 2.4 [Parallel类](#24-parallel类)
3. [线程同步技术](#三线程同步技术)
   - 3.1 [lock关键字](#31-lock关键字)
   - 3.2 [Monitor类](#32-monitor类)
   - 3.3 [Mutex](#33-mutex)
   - 3.4 [Semaphore](#34-semaphore)
4. [实际应用案例](#四实际应用案例)
   - 4.1 [文件批量处理](#41-文件批量处理)
   - 4.2 [高并发Web服务](#42-高并发web服务)
   - 4.3 [游戏开发中的应用](#43-游戏开发中的应用)
5. [性能优化与陷阱](#五性能优化与陷阱)
   - 5.1 [线程池优化](#51-线程池优化)
   - 5.2 [死锁预防](#52-死锁预防)
   - 5.3 [上下文切换开销](#53-上下文切换开销)
6. [异步编程模型](#六异步编程模型)
   - 6.1 [async/await原理](#61-asyncawait原理)
   - 6.2 [Task与线程的关系](#62-task与线程的关系)
7. [高级主题](#七高级主题)
   - 7.1 [线程局部存储](#71-线程局部存储)
   - 7.2 [内存屏障](#72-内存屏障)
   - 7.3 [CAS操作](#73-cas操作)
8. [总结与展望](#八总结与展望)

---

## 一、多线程基础概念

### 1.1 进程与线程的区别
进程是操作系统资源分配的基本单位,而线程是CPU调度的基本单位。一个进程可以包含多个线程,这些线程共享进程的资源(如内存空间、文件句柄等),但每个线程有自己的执行栈和程序计数器。

```csharp
// 获取当前进程信息示例
Process currentProcess = Process.GetCurrentProcess();
Console.WriteLine($"进程ID: {currentProcess.Id}");
Console.WriteLine($"线程数: {currentProcess.Threads.Count}");

1.2 多线程的应用场景


二、C#多线程实现方式

2.1 Thread类

最基本的线程创建方式,提供对线程的精细控制。

// Thread基础示例
Thread thread = new Thread(() => {
    Console.WriteLine($"子线程ID: {Thread.CurrentThread.ManagedThreadId}");
    Thread.Sleep(1000);
});
thread.Start();
Console.WriteLine($"主线程ID: {Thread.CurrentThread.ManagedThreadId}");

参数传递方式:

// 通过ParameterizedThreadStart传递参数
Thread paramThread = new Thread((obj) => {
    Console.WriteLine($"接收参数: {obj}");
});
paramThread.Start("Hello Thread");

2.2 ThreadPool

.NET提供的线程池管理,适合短生命周期任务。

// 线程池示例
ThreadPool.QueueUserWorkItem(state => {
    Console.WriteLine($"线程池线程ID: {Thread.CurrentThread.ManagedThreadId}");
});

2.3 Task

基于任务的异步模式(TAP),推荐使用方式。

// Task基础示例
Task.Run(() => {
    Console.WriteLine($"Task线程ID: {Thread.CurrentThread.ManagedThreadId}");
});

// 带返回值的Task
Task<int> task = Task.Run(() => {
    return DateTime.Now.Second;
});
Console.WriteLine($"当前秒数: {task.Result}");

2.4 Parallel类

简化数据并行操作。

// Parallel.For示例
Parallel.For(0, 10, i => {
    Console.WriteLine($"并行执行{i}, 线程ID: {Thread.CurrentThread.ManagedThreadId}");
});

// Parallel.ForEach示例
List<string> data = new List<string> { "A", "B", "C", "D" };
Parallel.ForEach(data, item => {
    Console.WriteLine($"处理{item}, 线程ID: {Thread.CurrentThread.ManagedThreadId}");
});

三、线程同步技术

3.1 lock关键字

最简单的同步机制,基于Monitor实现。

private static readonly object _lockObj = new object();
private static int _counter = 0;

void Increment()
{
    lock(_lockObj) {
        _counter++;
    }
}

3.2 Monitor类

比lock更灵活,可设置超时。

Monitor.Enter(_lockObj);
try {
    _counter++;
}
finally {
    Monitor.Exit(_lockObj);
}

3.3 Mutex

跨进程的同步原语。

using Mutex mutex = new Mutex(false, "Global\\MyMutex");
try {
    mutex.WaitOne();
    // 临界区代码
}
finally {
    mutex.ReleaseMutex();
}

3.4 Semaphore

控制并发访问数量的信号量。

SemaphoreSlim semaphore = new SemaphoreSlim(3); // 允许3个并发

async Task AccessResource()
{
    await semaphore.WaitAsync();
    try {
        // 访问受限资源
    }
    finally {
        semaphore.Release();
    }
}

四、实际应用案例

4.1 文件批量处理

// 多线程文件处理
string[] files = Directory.GetFiles("D:\\Data");
Parallel.ForEach(files, file => {
    byte[] data = File.ReadAllBytes(file);
    // 处理文件内容
});

4.2 高并发Web服务

// ASP.NET Core中的并发处理
[HttpGet]
public async Task<IActionResult> GetData()
{
    var data = await _service.FetchDataAsync();
    return Ok(data);
}

4.3 游戏开发中的应用

// Unity中的多线程计算
void Update() {
    Task.Run(() => {
        // 计算密集型逻辑
        Vector3 newPosition = CalculateMovement();
        
        // 必须回到主线程修改游戏对象
        UnityMainThreadDispatcher.Instance.Enqueue(() => {
            aiCharacter.transform.position = newPosition;
        });
    });
}

五、性能优化与陷阱

5.1 线程池优化

// 设置线程池最小线程数
ThreadPool.SetMinThreads(50, 50);

// 监控线程池状态
ThreadPool.GetAvailableThreads(out int worker, out int io);
Console.WriteLine($"可用工作线程: {worker}, IO线程: {io}");

5.2 死锁预防

典型死锁场景:

object lock1 = new object();
object lock2 = new object();

void Method1() {
    lock(lock1) {
        Thread.Sleep(100);
        lock(lock2) { /* ... */ }
    }
}

void Method2() {
    lock(lock2) {
        Thread.Sleep(100);
        lock(lock1) { /* ... */ }
    }
}

5.3 上下文切换开销


六、异步编程模型

6.1 async/await原理

async Task<string> GetDataAsync()
{
    HttpClient client = new HttpClient();
    string result = await client.GetStringAsync("http://example.com");
    return result.ToUpper();
}

6.2 Task与线程的关系


七、高级主题

7.1 线程局部存储

[ThreadStatic]
private static int _threadSpecificValue;

void ThreadMethod()
{
    _threadSpecificValue = Thread.CurrentThread.ManagedThreadId;
    Console.WriteLine(_threadSpecificValue);
}

7.2 内存屏障

int _value = 0;
bool _complete = false;

void Writer() {
    _value = 100;
    Thread.MemoryBarrier(); // 确保写入顺序
    _complete = true;
}

void Reader() {
    if (_complete) {
        Thread.MemoryBarrier(); // 确保读取顺序
        Console.WriteLine(_value);
    }
}

7.3 CAS操作

int _value = 0;

void Increment() {
    int current, newValue;
    do {
        current = _value;
        newValue = current + 1;
    } while (Interlocked.CompareExchange(ref _value, newValue, current) != current);
}

八、总结与展望

  1. 技术选型建议

    • 简单任务 → ThreadPool
    • 复杂控制 → Task
    • 数据并行 → Parallel
    • 跨进程 → Mutex
  2. 发展趋势

    • async/await成为主流
    • ValueTask优化
    • 更智能的线程池
    • 与协程的结合
  3. 最佳实践

    • 避免长时间持有锁
    • 合理设置线程优先级
    • 使用CancellationToken支持取消
    • 始终处理异步异常

“多线程编程就像在雷区跳舞,规则越清晰,步伐越安全。” —— 匿名开发者

[全文完] “`

注:实际9600字内容需要展开每个章节的详细解释、更多代码示例、性能对比数据、图表说明等。本文档提供了完整框架和核心代码示例,可根据需要扩展具体内容。

推荐阅读:
  1. Python多线程机制接口举例分析
  2. C#数组操作举例分析

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

上一篇:Python怎么实现修改图片分辨率

下一篇:Python enumerate()计数器简化循环的方法是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》