异步编程

本文详细介绍了C#中的异步编程概念及其重要性,通过对比同步与异步操作,解释了异步如何帮助提高应用程序效率。文章还提供了三种进行异步调用的方式:使用Thread、线程池(ThreadPool)及Task,并展示了await和async关键字的用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为什么需要异步,异步对可能起阻止作用的活动(例如,应用程序访问 Web 时)至关重要。 对 Web 资源的访问有时很慢或会延迟。 如果此类活动在同步过程中受阻,则整个应用程序必须等待。 在异步过程中,应用程序可继续执行不依赖 Web 资源的其他工作,直至潜在阻止任务完成。

在前面的章节已经知道了C#有三种方式进行异步调用:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication39
{
    class Program
    {
        static void Main(string[] args)
        {
            CountdownEvent handler = new CountdownEvent(2);
            //使用Thread调用
            new Thread(() => { Test("Thread"); handler.Signal(); }).Start();
            //使用线程池调用
            ThreadPool.QueueUserWorkItem((state) => { Test("ThreadPool"); handler.Signal(); });
            //使用Task调用
            Task task = Task.Run(() => Test("Task"));
            Console.WriteLine("Main Thread");



            //等待所有工作线程完成之后结束
            handler.Wait();
            //等待Task完成
            Task.WaitAll(task);
            Console.WriteLine("Main End");
        }
        static void Test(string caller)
        {
            Thread.Sleep(1000);
            Console.WriteLine("caller:{0} Hello World", caller);
        }
    }
}

原理

其实不管是Task,ThreadPool,本质最终都是Thread。只不过微软帮我们在简化线程控制的复杂度。

线程池是CLR中事先定义好的一些线程。Task取的线程池,只不过在语法上,可以非常方便取返回值。

异步会提高程序的运行速度吗

  多线程会提高程序的效率,不会提高运行速度。

  这就好比这一个任务让前台花1个小时。前台完成10分钟的时候

  打电话给经理,让他安排一个人来干30分钟(new Thread()),他干剩下的20分钟。(创建线程,需要时间,内存资源)

  或者从旁边空闲的同事中(ThreadPool 或 Task),拉一个人过来干30分钟。他干剩下的20分钟。(需要的时间少,资源本来就存在)

  从上看出,异步会让一份任务时间变长。资源消耗更多。但是可以让前台(UI线程)空闲下来,听从领导(用户)指挥。

使用await和async

  1. 凡是使用await关键字的方法,都必须打上async标记。

  2. async表示方法内有异步方法,调用async方法,会立刻另起线程执行。

  3. await只是显示等待线程结束。await表示等待异步方法执行完,并取返回值。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication39
{
    class Program
    {
        static void Main(string[] args)
        {
            StartAsync(); //main不能使用async

            Console.WriteLine("这是Main方法,线程ID:{0}", CurrentThreadID);
            Console.Read();
        }
        static async Task StartAsync()
        {
            Task<string> t_result = MethodAsync();

            Thread.Sleep(500);//模拟执行大量耗时操作
            Console.WriteLine("这是StartAsync方法,线程ID:{0}", CurrentThreadID); //完成标记

            string result = await t_result; //等待取异步返回结果
            Console.WriteLine("Main End {0},线程ID:{0}",result, CurrentThreadID); //主线程结束标记
        }
        static async Task<string> MethodAsync()
        {
            return await Task.Run(() =>
             {
                 Console.WriteLine("这是MethodAsync方法0,线程ID:{0}", Thread.CurrentThread.ManagedThreadId.ToString());
                 Thread.Sleep(1000);//模拟执行大量耗时操作
                 Console.WriteLine("这是MethodAsync方法1,线程ID:{0}", CurrentThreadID);
                 return "Hello World";
             });
        }
        public static string CurrentThreadID
        {
            get
            {
                return Thread.CurrentThread.ManagedThreadId.ToString();
            }
        }
    }
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值