Intern Day98 - C#Task异步编程简单使用
为什么引入Task
我目前接触到的项目已经不再使用 线程池ThreadPool 了,而是用 Task 。原因如下:
-
Task有线程池有的优点:这两者比Thread创建线程更优,因为可以 减少线程的创建 + 减小系统开销 。
-
并且,Task解决了C#中线程池的缺点:线程池的缺点是我们 不能控制线程池中线程的执行顺序 + 不能获取线程池内线程的通知(取消/异常/完成) 。
Task的三种创建和执行方式
PS:这几种都是异步的方式。
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
// 方式1:
// 创建:用new Task(Action action)去实例化一个Task + 启动:用Start方法
var task1 = new Task(() =>
{
Thread.Sleep(1000);
Console.WriteLine($"Thread Task1 ID = {Thread.CurrentThread.ManagedThreadId}");
});
task1.Start();
// ---------------------------------------------------------------------------------
// 方式2:
// Task.Factory.StartNew(Action action) 创建+启动一个Task
var task2 = Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
Console.WriteLine($"Thread Task2 ID = { Thread.CurrentThread.ManagedThreadId}");
});
// ---------------------------------------------------------------------------------
// 方式3:
// Task.Run(Action action)将任务放在线程池队列,返回并启动一个Task
var task3 = Task.Run(() =>
{
Thread.Sleep(1000);
Console.WriteLine($"Thread Task3 ID = { Thread.CurrentThread.ManagedThreadId}");
});
// ---------------------------------------------------------------------------------
Console.WriteLine("Execute the Main Thread!");
Console.ReadKey(); // *** must need
}
}
我们会发现,每次运行,子线程的ID总是在变化,但是主线程永远是输出的第一个,说明:Task不会阻塞主线程。
但是需要注意的是:task.Resut获取结果时会阻塞线程。
Task在项目中的写法
下面随便拿了一个项目中的写法,具体怎么写根据需求来:
public static Task Asyncxxx<xxx>(xxx,xxx,……) //根据需要进行变形
{
……
var task = Task.Run(async () =>
{
……
});
return task;
}