Task任务的三种启动方式和对比选择
namespace thinger.TaskDemo
{
class Program
{
static void Main(string[] args)
{
// Test1();
// Test2();
Test3();
Console.ReadLine();
}
//【1】创建Task对象,然后调用Start方法启动线程
static void Test1()
{
Task task = new Task(() =>
{
//在这个地方编写需要的具体任务....
Console.WriteLine("new 一个新的Task,对应的子线程ID=" + Thread.CurrentThread.ManagedThreadId);
});
task.Start();
}
//【2】使用Task的静态方法Run方法直接启动线程
static void Test2()
{
Task task = Task.Run(() =>
{
//在这个地方编写需要的具体任务....
Console.WriteLine("使用Task中的Run方法,对应的子线程ID=" + Thread.CurrentThread.ManagedThreadId);
});
}
//【3】使用Factory启动
static void Test3()
{
Task task = Task.Factory.StartNew(() =>
{
//在这个地方编写需要的具体任务....
Console.WriteLine("使用Task中的Factory.StartNew方法,对应的子线程ID=" + Thread.CurrentThread.ManagedThreadId);
});
}
}
}
Task三种启动方式比较
【1】Task对象的Start方法启动,适合在符合条件情况下去启动,也就是可以按照需求启动,灵活控制。
【2】Run方法,是定义后直接启动。适合马上启动的情况。
【3】ask.Factory.StartNew,也是直接启动线程。
1. 创建 Task 对象然后调用 Start 方法启动线程
static void Test1()
{
Task task = new Task(() =>
{
Console.WriteLine("new 一个新的Task,对应的子线程ID=" + Thread.CurrentThread.ManagedThreadId);
});
task.Start();
}
优点:
- 提供了对任务的最大控制权,例如可以设置任务的创建选项(如长期运行的任务)。
- 可以在启动之前配置任务的行为。
缺点:
- 这种方法比较繁琐,因为它需要先创建
Task
实例然后再显式地调用Start()
方法。 - 不推荐这种方式来启动一个任务,因为可能会遇到竞争条件,即
Start()
被调用之前,任务可能已经被其他代码意外启动。
2. 使用 Task 的静态方法 Run 方法直接启动线程
static void Test2()
{
Task task = Task.Run(() =>
{
Console.WriteLine("使用Task中的Run方法,对应的子线程ID=" + Thread.CurrentThread.ManagedThreadId);
});
}
优点:
- 简单直观,适合快速启动不需要额外配置的任务。
- 自动将工作项排队到线程池,并立即开始执行。
缺点:
- 缺乏灵活性,不能指定任务的创建选项。
- 主要用于CPU绑定的工作,对于I/O绑定的操作,应该考虑使用 async/await 模式。
3. 使用 Factory 启动
static void Test3()
{
Task task = Task.Factory.StartNew(() =>
{
Console.WriteLine("使用Task中的Factory.StartNew方法,对应的子线程ID=" + Thread.CurrentThread.ManagedThreadId);
});
}
优点:
- 提供比
Task.Run
更多的灵活性,可以通过StartNew
的重载方法指定更多参数,比如任务的创建选项、取消令牌等。 - 适用于更复杂的任务调度需求。
缺点:
- 相对于
Task.Run
来说稍微复杂一些。 - 如果不正确地使用(例如没有正确处理同步上下文),可能会导致UI应用程序的问题。
4. 总结
总的来说,如果你只需要简单地启动一个后台任务并且不需要额外配置,Task.Run
是最简便的选择。如果你需要更多的控制和配置选项,那么 Task.Factory.StartNew
是更好的选择。而直接创建 Task
并调用 Start()
的方法通常不是首选,除非有特殊原因需要这么做。