


我们使用异步编程可以自己开辟线程,也可以使用async,await关键字来实现
例如我们在主线程直接执行一个方法是会阻塞主线程的
- static void Main(string[] args)
- {
- Console.WriteLine("主线程测试开始..");
- Show();
- Console.WriteLine("主线程测试结束..");
- Console.ReadLine();
- }
-
- static void Show()
- {
- for (int i = 0; i < 5; i++)
- {
- Console.WriteLine("异步执行" + i.ToString() + "..");
- Task.Delay(1000); //模拟耗时操作
- }
- }
输出完后,主线程才会执行
下面我们使用async,await来实现一个没有返回值的异步方法
没有返回值的异步方法很简单,写好了我们直接调用就好了
- static void Main(string[] args)
- {
- Console.WriteLine("主线程测试开始..");
- ShowAsync();
- Console.WriteLine("主线程测试结束..");
- Console.ReadLine();
- }
-
-
- static async void ShowAsync()
- {
- for (int i = 0; i < 5; i++)
- {
- Console.WriteLine("异步执行" + i.ToString() + "..");
- await Task.Delay(1000); //模拟耗时操作
- }
- }
效果如下,可以看到并没有阻塞主线程:
这里要注意Task.Delay返回的就是一个Task,所以前面可以使用await等待他
下面我们使用async,await来实现一个有返回值的异步方法
由于有返回值不想去影响主函数的方法,我们需要写一个方法来中转一下,在这个中转方法中去取到返回值
当然也可以把调用他的方法也修改为可以等待的异步方法,如果不想修改它就单独写一个方法吧
- class Program
- {
- static void Main(string[] args)
- {
- Console.WriteLine("主线程测试开始..");
- MethodAsync();
- Console.WriteLine("主线程测试结束..");
- Console.ReadLine();
- }
-
- /// <summary>
- /// 获取返回值的中转方法
- /// </summary>
- static async void MethodAsync()
- {
- Console.WriteLine("开始异步代码");
- int result = await ShowRAsync();
- Console.WriteLine("异步代码执行完毕" + result);
- }
-
-
- static async Task<int> ShowRAsync()
- {
- for (int i = 0; i < 5; i++)
- {
- Console.WriteLine("异步执行" + i.ToString() + "..");
- await Task.Delay(1000); //模拟耗时操作
- }
- return 200;
- }
-
- }
效果如下:
tip:这里的ShowRAsync方法是返回的一个task,所以调用它的方法MethodAsync也可以使用await方法等待
相当于加了await就可以得到一个task的执行,但是那个方法必须申明async,那个方法就是一个异步方法
如果在方法当中不需要等待返回值,只是一个异步调用的话,就没有必要去使用async了,直接Task.Run去异步执行就好了
例如提供一个很简单的异步调用日志的方法
- public static void AddLogAsync(string content, string type, string remark)
- {
- Task.Run(() =>
- {
- AddLog(content, type, remark);
- });
- }
有返回值:
- public Task<int> AddTNMessageAsync(TNMessage _message)
- {
- return Task.Run<int>(() =>
- {
- int count = EfHelper.Add(_message);
- return count;
- });
- }
查询数据库的时候的异步(ef 异步):
- public Task<BlogSet> GetBlogSetByUIdAsync(int? _userid)
- {
- return context.BlogSet.Where(a => a.UserId == _userid).FirstOrDefaultAsync();
- }
微软官方的 一个例子:
- public class PriorityListViewComponent : ViewComponent
- {
- private readonly ToDoContext db;
-
- public PriorityListViewComponent(ToDoContext context)
- {
- db = context;
- }
-
- public async Task<IViewComponentResult> InvokeAsync(int maxPriority, bool isDone)
- {
- var items = await GetItemsAsync(maxPriority, isDone);
- return View(items);
- }
- private Task<List<TodoItem>> GetItemsAsync(int maxPriority, bool isDone)
- {
- return db.ToDo.Where(x => x.IsDone == isDone && x.Priority <= maxPriority).ToListAsync();
- }
- }
我的个人理解:
async,await其实里边就是开辟的线程,用这两个可以形成一种标准,一种规范,让人一看就知道是一个异步方法。也封装了很多,让我们方便使用。如果不需要返回值的话,直接调用。如果需要取到返回值就用另外一个包含async的去做一下中转,当然如果想把异步方法当同步使用也可以
另外他们一般都配合task使用
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)
雨雨雨雨辰
阻塞!