您现在的位置是:首页 > .NET相关网站首页

.NET Task任务的使用方法

简介 Task的使用方法

Task简介

任务(Task)是一个管理并行工作单元的轻量级对象。它通过使用CLR的线程池来避免启动专用线程,可以更有效率的利用线程池。

System.Threading.Tasks 命名空间下任务相关类有以下,分别有不同的作用:

类名 作用
Task 管理工作单元
Task<TResult> 管理带返回值的工作单元
TaskFactory 创建任务
TaskFactory<TResult> 创建任务或者有相同返回值的延续任务
TaskScheduler 管理任务调度
TaskCompletionSource 手动控制任务工作流

创建与启动Task任务

创建任务有以下两种方法:

一、通过Task.Factory.StartNew创建并启动任务;

实例代码如下:

public void DoSomething(){
    //.....
}
public string GetSomething(){
    //.....
}
/* 1.通过Task.Factory.StartNew创建并启动任务; */

//没有返回值
Task.Factory.StartNew(()=>DoSomething());

//有返回值
var taskResult2=Task.Factory.StartNew(()=>GetSomething());

Task.Factory.StartNew方法是创建并立刻启动任务,这块需要注意。

二、实例化Task创建,然后手动启动任务。

实例代码如下:

//异步执行
var task = new Task<string>(() => GetSomething);
task.Start();//异步执行

//同步执行
var task = new Task<string>(() => GetSomething);
task.RunSynchronously();//同步执行,等待任务结束后,才继续执行后续的代码。

等待任务

任务可以通过Wait()成员方法或Result属性来等待任务完成。

一、Task.WaitAny()方法可等待多个任务中的任意一个完成。

示例:

var tasks = new Task[10];
for (int i = 0; i < tasks.Length; i  )
{
    int taskIndex = i;
    tasks[i] = Task.Factory.StartNew(() =>
    {
        //dosomething...
    });
}
Task.WaitAny(tasks);//等待tasks任意一个任务完成后,就继续向下执行

二、Task.WaitAny()方法等待所有任务完成。

示例:

var tasks = new Task[3];
for (int i = 0; i < tasks.Length; i  )
{
    int taskIndex = i;
    tasks[i] = Task.Factory.StartNew(() =>
    {
        //dosomething...
    });
}
Task.WaitAll(tasks);//等待tasks所有任务完成后,才继续向下执行

Task取消任务执行

Task中有一个专门的类CancellationTokenSource来取消任务执行。

示例如下:

    static void Main(string[] args)
        {
            CancellationTokenSource source = new CancellationTokenSource();
            int index = 0;
            //开启一个task执行任务
            Task task1 = new Task(() =>
              {
                  while (!source.IsCancellationRequested)
                  {
                      Thread.Sleep(1000);                      Console.WriteLine($"第{  index}次执行,线程运行中...");
                  }
              });
            task1.Start();
            //五秒后取消任务执行
            Thread.Sleep(5000);
            //source.Cancel()方法请求取消任务,IsCancellationRequested会变成true
            source.Cancel();
            Console.ReadKey();
        }

CancellationTokenSource的功能不仅可以取消任务执行,也可以使用 source.CancelAfter(5000) 实现5秒后自动取消任务,还可以通过 source.Token.Register(Action action) 注册一个取消任务后触发的回调函数,回调函数会在任务被取消时执行。

示例:

    static void Main(string[] args)
        {
            CancellationTokenSource source = new CancellationTokenSource();
            //注册任务取消的事件
            source.Token.Register(() =>
            {
                //任务取消后执行的操作..
            });

            int index = 0;
            //开启一个task执行任务
            Task task1 = new Task(() =>
              {
                  while (!source.IsCancellationRequested)
                  {
                      Thread.Sleep(1000);
                      Console.WriteLine($"第{  index}次执行,线程运行中...");
                  }
              });
            task1.Start();
            //延时取消,效果等同于Thread.Sleep(5000);source.Cancel();
            source.CancelAfter(5000);
            Console.ReadKey();
        }

异步方法(async/await)

async/await是在C#5.0中出现的关键字。

async(异步)是方法上的关键字,我们可以将这个关键字添加到方法上,表示该方法是个异步方法;

await(等待)是在调用异步方法时使用的,表示需要等待异步方法执行完毕后再继续向下执行。

需要注意,使用async关键字的方法,返回值必须用Task包装,没有返回值也需要返回Task,这样调用方才能根据返回的Task判断异步方法执行的状态。

看个例子:

//首先创建一个没有返回值的异步方法
public async Task DoSomething(){
    //开启一个线程,并等待。
    await Task.Run(()=>{
        //各种操作...
    });
}

static void Main(){
    //同步调用,等待方法执行完成后,才继续向下执行。
    DoSomething().Wait();

    //异步调用,不等待方法执行完成。
    DoSomething().Start();
    //也可以这样,但是Main方法也需要添加上async关键字和Task包装的返回值。
    await DoSomething();
}

可以看到,async/await是基于Task的,Task是为了更有效的控制线程池中的线程。async、await、Task是C#中更先进的,也是微软大力推广的特性,所以我们在开发中可以尝试多使用Task处理IO任务来提高任务执行效率。

以上是本文的所有内容。

文章评论

Top Error:远程服务器返回错误: (403) 已禁止。