码迷,mamicode.com
首页 > Windows程序 > 详细

C# 异步方法的使用

时间:2018-04-07 01:13:58      阅读:300      评论:0      收藏:0      [点我收藏+]

标签:getc   tle   read   nbsp   必须   att   mil   使用   bsp   

?  前言

C# 中的异步方法是 C#5.0 才有的新特性,可以在执行当前方法的同时异步的去执行其他方法。

 

?  什么是异步方法

1)   异步方法,是指在执行当前方法的同时,去执行其他异步方法,但不会阻塞当前方法的线程。

2)   使用了 async 修饰符的方法称为异步方法,通常配合 await 运算符和 Task 异步任务一起使用。

3)   Task 分为两种:

1.   Task,表示可以执行一个异步操作,声明如下:

public class Task : IAsyncResult, IDisposable { }

2.   Task<TResult>,表示可以执行带有返回值的异步操作,声明如下:

public class Task<TResult> : Task { }

4)   异步方法的返回类型必须为 voidTaskTask<TResult> 中的其中一种。

1.   void,表示无返回值,不关心异步方法执行后的结果,一般用于仅仅执行某一项任务,但是不关心结果的场景。

2.   Task,表示异步方法将返回一个 Task 对象,该对象通常用于判断异步任务是否已经完成,可以使用 taskObj.Wait() 或者 taskObj.IsCompleted 判断。

3.   Task<TResult>,表示异步方法将返回一个 Task<TResult> 对象,该对象的 Result 属性则是异步方法的执行结果,调用该属性时将阻塞当前线程(异步方法未执行完时)。

?  总结下:void 不关心结果;Task 只关心是否运行完成;Task<TResult> 不止关心是否运行完成,还要获得运行结果。

 

1.   通过几个例子来看下异步方法的特征

1)   代码如下:

public void AsyncTest()

{

    ConsoleExt.WriteLine("AsyncTest() 方法开始执行,线程Id为:{0}", GetCurrentThreadId());

    Test1();

    ConsoleExt.WriteLine("AsyncTest() 方法结束执行,线程Id为:{0}", GetCurrentThreadId());

}

 

public async void Test1()

{

    ConsoleExt.WriteLine("Test1() 方法开始执行,线程Id为:{0}", GetCurrentThreadId());

    Task task = Task.Run(() =>

    {

        ConsoleExt.WriteLine("Test1() 方法中的 Task 开始执行,线程Id为:{0}", GetCurrentThreadId());

        ConsoleExt.WriteLine("Test1() 方法中的 Task 结束执行,线程Id为:{0}", GetCurrentThreadId());

    });

    ConsoleExt.WriteLine("Test1() 方法结束执行,线程Id为:{0}", GetCurrentThreadId());

}

运行以上代码:

技术分享图片

以上代码在 Test() 方法中,重新开启了一个新的 Task 去执行另一个任务,开启后当前线程并不会等等,则继续往下执行。

 

2)   调用 Task Wait() 方法(阻塞线程)

Task task = Task.Run(() =>

{

    ConsoleExt.WriteLine("Test1() 方法中的 Task 开始执行,线程Id为:{0}", GetCurrentThreadId());

    ConsoleExt.WriteLine("Test1() 方法中的 Task 结束执行,线程Id为:{0}", GetCurrentThreadId());

});

task.Wait();

运行以上代码:

技术分享图片

可见,调用 Wait() 方法后,当前线程被阻塞了,直到 Task 执行完成后,当前线程才继续执行。

 

3)   修改 Test1() 方法

public async void Test1()

{

    ConsoleExt.WriteLine("Test1() 方法开始执行,线程Id为:{0}", GetCurrentThreadId());

    await Task.Run(() =>

    {

        ConsoleExt.WriteLine("Test1() 方法中的 Task 开始执行,线程Id为:{0}", GetCurrentThreadId());

        ConsoleExt.WriteLine("Test1() 方法中的 Task 结束执行,线程Id为:{0}", GetCurrentThreadId());

    });

    ConsoleExt.WriteLine("Test1() 方法结束执行,线程Id为:{0}", GetCurrentThreadId());

}

运行以上代码:

技术分享图片

1.   以上代码在 Test() 方法上加了 async 关键字,并且使用 await 关键字等待异步任务执行完成,当前线程并没有阻塞。

2.   注意:当前线程遇到 await 时,则立刻回到调用方法继续往下执行。而 Task 执行完成之后将执行 await 之后的代码,并且与 await 之前的线程不是同一个。

C# 异步方法的使用

标签:getc   tle   read   nbsp   必须   att   mil   使用   bsp   

原文地址:https://www.cnblogs.com/abeam/p/8729508.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!