异步编程(基础)

1.异步编程并不是多线程

2.异步编程只是在IO操作/CPU操作 将主线程切换出去执行其他操作,不阻塞主线程,从而提升系统并发性能

3.异步并不能提升程序本身运行速度,只是能在同一时间点处理更多的任务。

 

举个烧水的例子(如图):

 

上图说明。从开始烧水到水开 不管同步还是异步,时间是相同的,只是人(主线程)在中途可以做更多的事情。

 

 

线程的切片也是需要开销,如果当前没有别的事情,只是烧水,还有必要异步吗?你觉得呢?

 

c#异步编程语法

异步编程方法用 async 修饰

1.返回值一般是Task<T> T为返回值类型 返回值为空 则 返回 Task

2.方法名后面标记为Async(标明该方法为异步方法)例子:HttpGetString(同步)   HttpGetStringAsync(异步)   

3.获取异步方法的实际返回值在调用方法前加上await  例子: string str=await HttpGetStringAsync(异步) ; 如果不加await 则返回值类型为 Task<T> 则不等待直接开启一个task线程运行改方法,可能改变方法执行顺序

4.await 异步非阻塞

 

static async Task Main(string[] args)
{

    int result = 0;
    //result= GetNumAsync(99).GetAwaiter().GetResult();//不推荐  肯能会死锁
    result = await GetNumAsync(99);//推荐
    
    Console.WriteLine("Hello, World!");
}
static async Task<int> GetNumAsync(int num)
{
    int result=0;
    for (int i = 0; i < num; i++)
    {
        result += num;
    }
    return result;
}

异步方法有什么好处?举个例子:(Winfrom程序)

 

 

 public Form1()
        {
            InitializeComponent();
        }
    //同步
        private void button1_Click(object sender, EventArgs e)
        {
            Thread.Sleep(2000);
            this.button1.Text = this.button1.Text + "done.";
        }
        //异步
        private async void button2_Click(object sender, EventArgs e)
        {
            await Task.Delay(2000);
            this.button2.Text = this.button2.Text + "done.";
        }

 

可以对比两个按钮点击后 是否可以拖动主窗体。  这就是主线程阻塞的一个简单例子,在Winform和WPF中经常出现界面卡死,一般是因为没有采用异步

 

 

 

异步编程原理:

在Await期间  系统会把当前线程返回线程池。等异步方法结束后在从线程池取出一个线程来继续执行后面的代码。

例子(获取当前线程ID):

using System.Text;
{//同步
        Console.WriteLine("同步Start:"+Thread.CurrentThread.ManagedThreadId);
        WriteText(9999);
        Console.WriteLine("同步End:" + Thread.CurrentThread.ManagedThreadId);
    }
    {//异步
        Console.WriteLine("异步Start" + Thread.CurrentThread.ManagedThreadId); 
        await WriteTextAsync(9999);   
        Console.WriteLine("异步End" + Thread.CurrentThread.ManagedThreadId);
    }


//同步
static void WriteText(int num)
{
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < num; i++)
    {
        builder.Append("ABCDEFG");
    } 
}


//异步
static Task WriteTextAsync(int num)
{
     StringBuilder builder = new StringBuilder();
    for (int i = 0; i < num; i++)
    {
        builder.Append("ABCDEFG");
    }
    Console.WriteLine("异步Doing" + Thread.CurrentThread.ManagedThreadId);
    return File.WriteAllTextAsync("d:/1.txt",builder.ToString());
}

 

 

 

从上例也可以看出 异步方法里的执行并没有在新的线程中执行,而是在执行完后,由另外的线程来继续执行后面的代码。

 

posted @ 2022-01-24 11:40  后跳  阅读(285)  评论(0编辑  收藏  举报