文章概述
本文旨在帮助读者理解C#中的异步编程与多线程概念,探讨如何在C#中实现多线程,并对比分析不同实现方法的特点及其适用场景。全文分为两大部分,第一部分介绍异步编程模式async/await及其与多线程的区别,第二部分则聚焦于C#中实现多线程的三种主要方法:Thread、ThreadPool和Task。
第一部分:异步编程模式 async/await 与多线程的区别
1.1 异步编程模式简介
异步编程模式是一种编程接口设计,主要用于处理并发流程需求。async/await是C#中实现异步编程的主要方式之一。这种模式允许开发者编写非阻塞代码,提高程序的响应性和效率。
1.2 async/await 使用示例
static void Main(string[] args)
{
_ = Async1();
Console.WriteLine("...............按任意键退出");
Console.ReadKey();
}
static async Task Async1()
{
Console.WriteLine("异步开始");
var r = await Async2();
var x = await Async3(r);
Console.WriteLine("结果是 {0}", r + x);
}
static async Task<int> Async2()
{
await Task.Delay(1000); // 异步延迟方法
return100;
}
static async Task<int> Async3(int x)
{
await Task.Delay(1000);
return x % 7;
}
执行结果:

通过上述代码可以看到,async关键字修饰的方法为异步方法,而await关键字用于标记异步操作的开始点。只有当两者配合使用时,方法才会真正实现异步执行。
1.3 async/await 的特点
- 异步执行:在遇到
await关键字时,方法会暂停执行,不会阻塞当前线程,而是允许其他任务继续运行。 - 代码可读性:虽然
async/await提高了代码的并发能力,但在某些情况下,可能会降低代码的可读性。 - 返回值类型:
async方法可以返回void、Task或Task<T>。
第二部分:C# 多线程实现方法
2.1 Thread 类
Thread类是最基本的多线程实现方式,适用于需要长时间运行的线程。
2.1.1 Thread 使用示例
static void Main(string[] args)
{
Thread thread = new Thread(Fun1);
// Thread thread = new Thread(() => Fun1(0)); // 多线程调用时有参数传递的写法
Console.WriteLine("异步开始");
// thread.IsBackground = true; // 设置为后台线程
thread.Start();
Console.WriteLine("...............按任意键退出");
Console.ReadKey();
}
static void Fun1()
{
var r = Fun2();
var x = Fun3(r);
Console.WriteLine("结果是 {0}", r + x);
}
static int Fun2()
{
Thread.Sleep(1000);
return100;
}
static int Fun3(int x)
{
Thread.Sleep(1000);
return x % 7;
}
执行结果:

2.1.2 Thread 的特点
- 内存消耗:每次创建新的
Thread对象都会消耗一定的内存(约1MB)。 - 线程类型:默认为前台线程,可以通过
IsBackground属性设置为后台线程。 - 参数传递:可以通过
Start方法传递参数,但参数类型必须为object。
2.2 ThreadPool 线程池
ThreadPool适用于需要频繁创建和销毁线程且每个线程运行时间较短的场景。
2.2.1 ThreadPool 使用示例
static void Main(string[] args)
{
Console.WriteLine("主线程执行!");
ThreadPool.SetMinThreads(1, 1); // 设置最小线程数
ThreadPool.SetMaxThreads(5, 5); // 设置最大线程数
for (int i = 1; i <= 10; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(testFun), i);
}
Console.WriteLine("主线程结束!");
Console.WriteLine("...............按任意键退出");
Console.ReadKey();
}
public static void testFun(object obj)
{
Console.WriteLine(string.Format("{0}:第{1}个线程", DateTime.Now.ToString(), obj.ToString()));
Thread.Sleep(5000);
}
2.2.2 ThreadPool 的特点
- 线程池特性:线程池是一个静态类,通过
QueueUserWorkItem方法将工作项加入线程池。 - 性能优势:避免了频繁创建和销毁线程的开销,提高了程序性能。
2.3 Task 类
Task类是C#中推荐的多线程实现方式,适用于大多数场景。
2.3.1 Task 使用示例
static void Main(string[] args)
{
Console.WriteLine("主线程执行!");
// 方法一
Task t1 = new Task(() =>
{
Console.WriteLine("方法1的任务开始工作……");
Thread.Sleep(5000);
Console.WriteLine("方法1的任务工作完成……");
});
t1.Start();
// 方法二
Task.Run(() =>
{
Console.WriteLine("方法2的任务开始工作……");
Thread.Sleep(5000);
Console.WriteLine("方法2的任务工作完成……");
});
// 方法三
var t3 = Task.Factory.StartNew(() =>
{
Console.WriteLine("方法3的任务开始工作……");
Thread.Sleep(5000);
Console.WriteLine("方法3的任务工作完成……");
});
Console.WriteLine("主线程结束!");
Console.WriteLine("...............按任意键退出");
Console.ReadKey();
}
2.3.2 Task 的特点
- 灵活性:提供了丰富的API,支持多种管理和控制方法。
2.4 Task 的高级用法
2.4.1 带返回值的 Task
static void Main(string[] args)
{
Console.WriteLine("主线程执行!");
Task<int> task = CreateTask("Task 1");
task.Start();
int result = task.Result;
Console.WriteLine("Task 1 Result is: {0}", result);
Console.WriteLine("主线程结束!");
Console.WriteLine("...............按任意键退出");
Console.ReadKey();
}
static Task<int> CreateTask(string name)
{
returnnew Task<int>(() => TaskMethod(name));
}
static int TaskMethod(string name)
{
Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(TimeSpan.FromSeconds(2));
return42;
}
2.4.2 ContinueWith 方法
static void Main(string[] args)
{
Console.WriteLine("主线程执行!");
Task t1 = new Task(() =>
{
Console.WriteLine("方法1的任务开始工作……");
Thread.Sleep(5000);
Console.WriteLine("方法1的任务工作完成……");
});
t1.Start();
t1.ContinueWith(t =>
{
Console.WriteLine("方法1的任务工作完成了!");
});
Console.WriteLine("主线程结束!");
Console.WriteLine("...............按任意键退出");
Console.ReadKey();
}
2.4.3 Task.WaitAll 方法
static void Main(string[] args)
{
Console.WriteLine("主线程执行!");
Task t1 = new Task(() =>
{
Console.WriteLine("方法1的任务开始工作……");
Thread.Sleep(5000);
Console.WriteLine("方法1的任务工作完成……");
});
t1.Start();
Task t2 = new Task(() =>
{
Console.WriteLine("方法2的任务开始工作……");
Thread.Sleep(5000);
Console.WriteLine("方法2的任务工作完成……");
});
t2.Start();
Task.WaitAll(t1, t2);
Console.WriteLine("主线程结束!");
Console.WriteLine("...............按任意键退出");
Console.ReadKey();
}
总结
多线程是实现异步的一种方法,C#中常用的多线程实现方式包括Thread、ThreadPool和Task。具体选择哪种方法取决于应用场景:
- 频繁创建和销毁线程且运行时间较短:推荐使用
ThreadPool。 - 其他一般场景:推荐使用
Task,因其灵活性和性能优势。
希望本文能帮助读者更好地理解和应用C#中的异步编程和多线程技术。
参考资料
- 浅析C#中的Thread ThreadPool Task和async/await
- c#的async到不是不是异步,它和多线程是什么关系
请阅读原文
出处:https://www.cnblogs.com/hellohxs/p/14358776.html
版权申明:本文来源于网友收集或网友提供,如果有侵权,请转告版主,立即删除。
该文章在 2026/2/6 8:38:23 编辑过