欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

談?wù)剬?duì).NET中async/await的理解

 更新時(shí)間:2025年03月04日 16:47:13   作者:花之亡靈  
本文介紹了.NET中異步編程的概念,包括async和await關(guān)鍵字的使用,以及異步編程的性能提升機(jī)制,異步編程通過(guò)非阻塞操作提高了程序執(zhí)行效率,減少了主線程的等待時(shí)間,感興趣的朋友一起看看吧

一、什么是同步?什么是異步?

在.net中,async 和 await 是兩個(gè)關(guān)鍵字,async 關(guān)鍵字用于聲明一個(gè)方法是異步方法,該方法可以包含一個(gè)或多個(gè) await 表達(dá)式。await 關(guān)鍵字是用于在異步方法中等待一個(gè)任務(wù)(Task 或 Task<T>對(duì)象)的完成。在 async 方法中使用 await表達(dá)式時(shí),會(huì)暫停當(dāng)前方法的執(zhí)行,直到等待的任務(wù)完成。在這段時(shí)間內(nèi),主線程可以去執(zhí)行其它操作。

什么是同步:當(dāng)一個(gè)方法被調(diào)用時(shí),調(diào)用者需要等待該方法執(zhí)行完畢后才會(huì)繼續(xù)往下執(zhí)行,我們稱這種方法為同步方法。

什么是異步:當(dāng)一個(gè)方法被調(diào)用時(shí)立即返回,并獲取一個(gè)線程執(zhí)(Task)行該方法內(nèi)部的業(yè)務(wù)邏輯,而調(diào)用者不需要等待這個(gè)方法執(zhí)行完畢,我們稱這種方法為異步方法。

二、async/await是怎么提高性能的?

異步的好處在于非阻塞(調(diào)用線程不會(huì)暫停執(zhí)行去等待子線程完成),因此,我們可以把一些不需要立即使用結(jié)果、耗時(shí)的任務(wù)設(shè)為異步去執(zhí)行,可以提高程序的執(zhí)行效率。

比如,一個(gè)主線程需要執(zhí)行 5 個(gè)方法,假設(shè)每個(gè)方法的分別用時(shí)為 0.1s、0.2s、0.3s、0.4s、0.5s,如果在同步編程中,這個(gè)主線程的執(zhí)行用時(shí)大概為1.5秒。而如果把這5個(gè)方法寫(xiě)成異步的形式,那么這個(gè)主線程大概用時(shí)為0.5秒。

這是為什么呢?這是因?yàn)?,在同步方法中,主線程在調(diào)用方法時(shí),需要把這個(gè)方法執(zhí)行完成之后再繼續(xù)調(diào)用后續(xù)的方法,主線程執(zhí)行這5個(gè)方法就好比一根線穿5顆珠子一樣,一顆一顆來(lái),所以主線程執(zhí)行所用時(shí)間大概為1.5秒。而在異步方法中,主線程在調(diào)用異步方法時(shí),主線程不會(huì)立即去執(zhí)行異步方法的,而是在遇到異步方法中的 await語(yǔ)句后返回一個(gè)任務(wù)(Task),然后再繼續(xù)調(diào)用后續(xù)的方法,這些任務(wù)的執(zhí)行是由 task創(chuàng)建一個(gè)子線程去執(zhí)行的,主線程執(zhí)行這5個(gè)異步方法就好比5個(gè)人拿5根線同時(shí)穿5顆珠子,所用時(shí)間就是用時(shí)最多的那個(gè),所以主線程執(zhí)行時(shí)間大概為0.5秒。

問(wèn)題:怎么解決在調(diào)用異步函數(shù)時(shí),主線程繼續(xù)向下執(zhí)行后,主線程是怎么回收或管理這個(gè)異步方法的執(zhí)行結(jié)果的。

1、await等待執(zhí)行

public class Demo
{
    public async Task DemoAsync()
    {
        await Task.Delay(1000);
        Console.WriteLine("1秒后執(zhí)行");
    }
}
public Class Program
{
    static async Task Main(string[] args)
    {
        Demo demo = new Demo();
        // 使用 await 等待DemoAsync的執(zhí)行
        await demo.DemoAsync();
        Console.ReadKey();
    }
}

2、使用事件

internal class Program
{
    static void Main(string[] args)
    {
        Demo demo = new Demo();
        demo.OnEvent += (() =>
        {
            Console.WriteLine("事件訂閱");
        });
        demo.DemoAsync();
        Console.ReadKey();
    }
}
public class Demo
{
    public event Action OnEvent;
    public async Task DemoAsync()
    {
        Console.WriteLine("開(kāi)始執(zhí)行");
        await Task.Delay(1000);
        Console.WriteLine("1秒后執(zhí)行");
        OnEvent?.Invoke();
    }
}

3、回調(diào)函數(shù)

internal class Program
    {
    static void Main(string[] args)
    {
        Demo demo = new Demo();
        demo.DemoAsync(() =>
        {
            Console.WriteLine("回調(diào)函數(shù)");
        });
        Console.ReadKey();
    }
}
public class Demo
{
    public async Task DemoAsync(Action callback)
    {
        Console.WriteLine("開(kāi)始執(zhí)行");
        await Task.Delay(1000);
        callback?.Invoke();
        Console.WriteLine("1秒后執(zhí)行");
    }
}

4、使用異步方法但不等待結(jié)果

這種方法知識(shí)啟動(dòng)了異步操作而不需要結(jié)果,可以簡(jiǎn)單的調(diào)用異步方法而不使用 await。這種方式不會(huì)阻塞主線程,也不會(huì)處理異步操作的結(jié)果。

internal class Program
{
    static void Main(string[] args)
    {
        Demo demo = new Demo();
        demo.DemoAsync();
        Console.ReadKey();
    }
}
public class Demo
{
    public async Task DemoAsync()
    {
        Console.WriteLine("開(kāi)始執(zhí)行");
        await Task.Delay(1000);
        Console.WriteLine("1秒后執(zhí)行");
    }
}

5、將異步結(jié)果存儲(chǔ)在變量中

如果想要在某個(gè)時(shí)刻獲取到異步操作中的結(jié)果,可以將異步操作的結(jié)果存儲(chǔ)在變量中,然后再訪問(wèn)它。

internal class Program
{
    static void Main(string[] args)
    {
        Demo demo = new Demo();
        var demoResult = demo.DemoAsync();
        // 使用 wait等待異步的完成
        demoResult.Wait();
        if (demoResult.IsCompleted)
        {
            Console.WriteLine("str執(zhí)行完成");
            Console.WriteLine(demoResult.Result);
        }
        Console.ReadKey();
    }
}
public class Demo
{
    public async Task<string> DemoAsync()
    {
        Console.WriteLine("開(kāi)始執(zhí)行");
        await Task.Delay(1000);
        Console.WriteLine("1秒后執(zhí)行");
        return "異步返回結(jié)果";
    }
}

三、異步到底解決了什么?到底起到了什么樣的作用?

1、提高響應(yīng)性:使用 async 和 await 可以避免等待長(zhǎng)時(shí)間運(yùn)行的操作(如 IO 操作)阻塞主線程,從而提高應(yīng)用程序的響應(yīng)性。

2、簡(jiǎn)化異步操作:async 和 await 使得編寫(xiě)異步代碼更接近同步代碼的寫(xiě)法,這降低了異步編程的復(fù)雜性和出錯(cuò)的概率。

3、優(yōu)化資源使用:異步操作允許線程在等待任務(wù)完成時(shí)釋放,這樣可以為其它任務(wù)騰出資源,而不是處于空閑等待狀態(tài)。

四、在使用異步時(shí)的一些問(wèn)題的解決

1、異步的傳遞性問(wèn)題

異步方法的異步效果會(huì)在調(diào)用鏈上向上傳遞的,導(dǎo)致異步方法的調(diào)用鏈上的一些列方法也會(huì)被標(biāo)記為異步。這種情況通常發(fā)生在下面場(chǎng)景中:

調(diào)用異步方法:如果一個(gè)方法調(diào)用了一個(gè)異步方法,那么這個(gè)方法也需要標(biāo)記為 async,并使用 await 等待結(jié)果。返回類型的變化:異步方法通常以 Task 或 Task<T> 類型返回,這意味著調(diào)用這些異步方法的其他方法也需要更新其返回類型以匹配 Task 或 Task<T> 。

異步方法的傳遞性的避免:

1、不使用 await 調(diào)用異步函數(shù):如果在調(diào)用異步函數(shù)時(shí),不需要等待異步函數(shù)的返回結(jié)果,那么可以不適用 await關(guān)鍵字調(diào)用異步函數(shù)。

2、使用 Task.Run 來(lái)啟動(dòng)異步操作:Task.Run 方法可以用來(lái)啟動(dòng)一個(gè)新的異步操作,它會(huì)提供一個(gè)新的任務(wù)來(lái)異步函數(shù),從而避免了異步的傳遞性。

3、使用事件或回調(diào)來(lái)處理異步的結(jié)果:如果異步函數(shù)需要通知調(diào)用者操作已完成,可以使用事件或回調(diào)來(lái)代替直接的 await 調(diào)用。

4、將異步結(jié)果存放在變量中:如果需要等待異步操作的結(jié)果,但又不想立即等待它,可以將異步任務(wù)存儲(chǔ)在變量中,然后在需要訪問(wèn)時(shí)使用 wait 方法來(lái)等待異步的完成。

好記性不然爛筆頭,在學(xué)習(xí)的路上留下點(diǎn)痕跡。希望能給大家?guī)?lái)幫助,也期待你的點(diǎn)贊和討論。

到此這篇關(guān)于談?wù)剬?duì).NET中async/await的理解的文章就介紹到這了,更多相關(guān).net async await內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論