Task.Run()、Task.Factory.StartNew() 和 new Task() 的区别
Task.Run()
、Task.Factory.StartNew()
和 new Task()
是 .NET 中用于创建和启动任务的三种方式。它们在用法、灵活性和底层实现上有一些区别。下面我们将逐一讲解它们的异同点。
1. Task.Run()
Task.Run(() => SomeMethod());
特点:
- 简化用法:
Task.Run()
是用于简化任务启动的 API,它同时创建并启动任务,不需要手动调用Start()
。 - 线程池:
Task.Run()
默认在线程池中执行任务,不会创建独立的线程。Task.Run()
只能使用线程池,无法直接将任务分配给独立的线程。 - 异步执行:通常用于简化异步操作,不带复杂的配置选项。
适用场景:
- 适用于轻量级任务,需要快速将任务推送到线程池进行并发执行,推荐在处理非耗时的计算或 I/O 操作时使用。
- 简单的并发任务处理,比如后台加载数据、发送网络请求等。
使用方式:
Task task = Task.Run(() => SomeWork());
2. Task.Factory.StartNew()
Task.Factory.StartNew(() => SomeMethod(), TaskCreationOptions.LongRunning);
特点:
- 灵活性:
Task.Factory.StartNew()
提供了比Task.Run()
更高的灵活性,你可以设置更多的配置选项,如TaskCreationOptions
、TaskScheduler
等。 - 手动配置:可以设置
TaskCreationOptions
来控制任务的行为(如LongRunning
、PreferFairness
等),这是Task.Run()
所不具备的。 - 线程池与独立线程:默认情况下,它会将任务推送到线程池中,除非你指定了
TaskCreationOptions.LongRunning
,此时会创建一个独立的线程。
适用场景:
- 适合那些需要自定义任务行为的场景,如长时间运行的任务、需要控制任务执行策略的情况。
- 当你需要手动指定更多任务属性时(如使用自定义的
TaskScheduler
或手动设置CancellationToken
)。
使用方式:
Task task = Task.Factory.StartNew((</