一、基础线程启动方式
1. Thread类直接启动
// 基本线程启动
Thread thread = new Thread(new ThreadStart(SimpleMethod));
thread.Start();
void SimpleMethod()
{
Console.WriteLine($"线程ID:{Thread.CurrentThread.ManagedThreadId} 正在执行");
}
![图片[1]_C#线程启动的几种实现方法小结_知途无界](https://zhituwujie.com/wp-content/uploads/2025/06/d2b5ca33bd20250613102840.png)
2. 带参数的线程启动
// 使用ParameterizedThreadStart传递参数
Thread paramThread = new Thread(new ParameterizedThreadStart(ParamMethod));
paramThread.Start("参数数据");
void ParamMethod(object data)
{
Console.WriteLine($"接收到参数: {data}");
}
3. Lambda表达式简化
// 使用lambda表达式简化线程创建
Thread lambdaThread = new Thread(() =>
{
Console.WriteLine($"Lambda线程执行,ID:{Thread.CurrentThread.ManagedThreadId}");
});
lambdaThread.Start();
二、线程池技术
1. ThreadPool基础使用
// 使用线程池执行任务
ThreadPool.QueueUserWorkItem(state =>
{
Console.WriteLine($"线程池任务执行,状态: {state}");
}, "自定义状态");
2. 带返回值的线程池任务
// 使用Task.Run(本质也是线程池)
Task<int> task = Task.Run(() =>
{
Thread.Sleep(1000);
return 42;
});
Console.WriteLine($"任务结果: {task.Result}");
三、Task并行库(Task Parallel Library)
1. 基本Task启动
// 创建并启动Task
Task task = new Task(() =>
{
Console.WriteLine($"Task线程ID:{Thread.CurrentThread.ManagedThreadId}");
});
task.Start();
2. Task.Run快捷方式
// 使用Task.Run立即调度任务
Task.Run(() =>
{
Console.WriteLine("使用Task.Run启动的任务");
});
3. 带返回值的Task
Task<string> returnTask = Task.Run(() =>
{
return $"当前时间: {DateTime.Now}";
});
Console.WriteLine(returnTask.Result);
四、高级线程控制
1. 线程取消机制
// 使用CancellationToken取消线程
CancellationTokenSource cts = new CancellationTokenSource();
Task longRunningTask = Task.Run(() =>
{
while (!cts.IsCancellationRequested)
{
Console.WriteLine("任务执行中...");
Thread.Sleep(500);
}
}, cts.Token);
Thread.Sleep(2000);
cts.Cancel(); // 取消任务
2. 线程优先级设置
Thread priorityThread = new Thread(() =>
{
Console.WriteLine("高优先级线程执行");
});
priorityThread.Priority = ThreadPriority.Highest;
priorityThread.Start();
3. 线程本地存储
// 使用ThreadLocal实现线程本地存储
ThreadLocal<int> threadLocal = new ThreadLocal<int>(() => 42);
Thread t1 = new Thread(() =>
{
threadLocal.Value = 100;
Console.WriteLine($"线程1的值: {threadLocal.Value}");
});
Thread t2 = new Thread(() =>
{
threadLocal.Value = 200;
Console.WriteLine($"线程2的值: {threadLocal.Value}");
});
t1.Start();
t2.Start();
t1.Join();
t2.Join();
Console.WriteLine($"主线程的值: {threadLocal.Value}");
五、异步编程模型
1. async/await模式
// 使用async/await进行异步编程
async Task AsyncMethod()
{
Console.WriteLine($"开始异步方法,线程ID:{Thread.CurrentThread.ManagedThreadId}");
await Task.Run(() =>
{
Console.WriteLine($"异步任务中,线程ID:{Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(1000);
});
Console.WriteLine($"异步方法完成,线程ID:{Thread.CurrentThread.ManagedThreadId}");
}
await AsyncMethod();
2. 并行任务处理
// 使用Parallel.For并行处理
Parallel.For(0, 10, i =>
{
Console.WriteLine($"并行迭代{i},线程ID:{Thread.CurrentThread.ManagedThreadId}");
});
六、线程同步机制
1. lock关键字
// 使用lock实现线程同步
object lockObj = new object();
int sharedValue = 0;
List<Task> tasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
tasks.Add(Task.Run(() =>
{
lock (lockObj)
{
sharedValue++;
Console.WriteLine($"当前值: {sharedValue}");
}
}));
}
Task.WaitAll(tasks.ToArray());
2. Monitor类
// 使用Monitor实现更灵活的同步
object monitorObj = new object();
bool lockTaken = false;
try
{
Monitor.Enter(monitorObj, ref lockTaken);
// 临界区代码
Console.WriteLine("Monitor保护的代码区域");
}
finally
{
if (lockTaken)
{
Monitor.Exit(monitorObj);
}
}
3. Semaphore信号量
// 使用Semaphore控制并发访问
SemaphoreSlim semaphore = new SemaphoreSlim(3); // 允许3个并发
List<Task> semaphoreTasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
semaphoreTasks.Add(Task.Run(async () =>
{
await semaphore.WaitAsync();
try
{
Console.WriteLine($"任务{Task.CurrentId}进入,当前计数: {semaphore.CurrentCount}");
await Task.Delay(1000);
}
finally
{
semaphore.Release();
Console.WriteLine($"任务{Task.CurrentId}离开");
}
}));
}
await Task.WhenAll(semaphoreTasks);
七、最佳实践总结
- 选择适当的线程模型:
- CPU密集型任务:考虑使用
Parallel.For/ForEach - I/O密集型任务:优先使用
async/await - 长时间后台任务:使用
Task.Run或专用Thread
- 线程资源管理:
// 推荐使用Task.Factory配置长期运行任务
Task longRunning = Task.Factory.StartNew(() =>
{
// 长时间运行的操作
}, TaskCreationOptions.LongRunning);
- 异常处理:
try
{
Task faultedTask = Task.Run(() => throw new Exception("测试异常"));
faultedTask.Wait();
}
catch (AggregateException ae)
{
foreach (var e in ae.InnerExceptions)
{
Console.WriteLine($"捕获异常: {e.Message}");
}
}
- 性能考量:
- 避免过度创建线程(线程上下文切换开销)
- 合理设置线程池大小:
ThreadPool.SetMinThreads(50, 50); // 根据应用需求调整
ThreadPool.SetMaxThreads(500, 500);
- 现代替代方案:
- 对于新项目优先考虑
async/await模式 - 使用
ValueTask优化高频调用的异步方法 - 考虑使用
System.Threading.Channels进行生产者-消费者模式
八、各方法对比表
| 方法类型 | 典型使用场景 | 优点 | 缺点 |
|---|---|---|---|
| Thread | 需要精细控制的长期后台任务 | 完全控制优先级、状态 | 创建开销大,管理复杂 |
| ThreadPool | 短生命周期任务 | 自动管理,资源利用率高 | 无法控制具体线程 |
| Task | 大多数并发场景 | 功能丰富,支持async/await | 配置不当可能导致死锁 |
| async/await | I/O密集型操作 | 代码简洁,避免回调地狱 | 需要全链路支持异步 |
| Parallel | 数据并行处理 | 自动负载均衡 | 不适合任务间有依赖的情况 |
九、代码示例:综合线程应用
// 综合示例:并行处理+异步I/O+结果聚合
async Task ProcessDataAsync(List<string> urls)
{
var downloadTasks = urls.Select(async url =>
{
using var client = new HttpClient();
string content = await client.GetStringAsync(url);
return content.Length;
}).ToList();
int[] results = await Task.WhenAll(downloadTasks);
Console.WriteLine($"总下载字符数: {results.Sum()}");
}
// 调用示例
await ProcessDataAsync(new List<string>
{
"https://example.com",
"https://example.org",
"https://example.net"
});
通过以上多种线程启动和控制方式,C#开发者可以根据具体场景选择最适合的并发编程模型,构建高效可靠的应用程序。
© 版权声明
文中内容均来源于公开资料,受限于信息的时效性和复杂性,可能存在误差或遗漏。我们已尽力确保内容的准确性,但对于因信息变更或错误导致的任何后果,本站不承担任何责任。如需引用本文内容,请注明出处并尊重原作者的版权。
THE END

























暂无评论内容