欧美成人精品手机在线观看_69视频国产_动漫精品第一页_日韩中文字幕网 - 日本欧美一区二区

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

C# Async 和 Await 到底在做什么?

admin
2024年12月7日 8:8 本文熱度 342

1. 引言

在C#中,asyncawait關(guān)鍵字是用于實(shí)現(xiàn)異步編程的強(qiáng)大工具。它們的引入極大地簡化了異步代碼的編寫,使得開發(fā)人員能夠更容易地創(chuàng)建響應(yīng)式和高性能的應(yīng)用程序。但是,要真正理解它們的工作原理,我們需要深入探討它們?cè)诘讓拥降自谧鍪裁础?/p>

2. 異步編程的基本概念

在深入asyncawait之前,我們需要理解一些基本概念:

  • 同步執(zhí)行: 代碼按順序執(zhí)行,每個(gè)操作完成后才會(huì)進(jìn)行下一個(gè)。

  • 異步執(zhí)行: 允許長時(shí)間運(yùn)行的操作在后臺(tái)進(jìn)行,而不阻塞主線程。

  • 任務(wù)(Task): 表示一個(gè)異步操作。

  • 線程: 程序執(zhí)行的最小單位。

3. Async 和 Await 的基本用法

讓我們從一個(gè)簡單的例子開始:

static async Task Main(string[] args)
{
    var context = await GetWebContentAsync("http://www.baidu.com");
    Console.WriteLine(context);
}

public static async Task<string> GetWebContentAsync(string url)
{
    using (var client = new HttpClient())
    {
        string content = await client.GetStringAsync(url);
        return content;
    }
}

在這個(gè)例子中:

  • async關(guān)鍵字標(biāo)記方法為異步方法。

  • 方法返回Task,表示一個(gè)最終會(huì)產(chǎn)生string的異步操作。

  • await用于等待GetStringAsync方法完成,而不阻塞線程。

4. Async 方法的轉(zhuǎn)換過程

當(dāng)你使用async關(guān)鍵字標(biāo)記一個(gè)方法時(shí),編譯器會(huì)將其轉(zhuǎn)換為一個(gè)狀態(tài)機(jī)。這個(gè)過程大致如下:

  1. 創(chuàng)建一個(gè)實(shí)現(xiàn)了IAsyncStateMachine接口的結(jié)構(gòu)體。

  2. 將方法體轉(zhuǎn)換為狀態(tài)機(jī)的MoveNext方法。

  3. 每個(gè)await表達(dá)式都成為一個(gè)可能的暫停點(diǎn),對(duì)應(yīng)狀態(tài)機(jī)中的一個(gè)狀態(tài)。

async方法如何被分解為多個(gè)步驟,每個(gè)await表達(dá)式對(duì)應(yīng)一個(gè)狀態(tài)。

5. Await 的工作原理

await關(guān)鍵字的主要作用是:

  1. 檢查awaited任務(wù)是否已完成。

  2. 如果已完成,繼續(xù)執(zhí)行后續(xù)代碼。

  3. 如果未完成,注冊(cè)一個(gè)回調(diào)并返回控制權(quán)給調(diào)用者。

讓我們通過一個(gè)例子來詳細(xì)說明:

public async Task DoWorkAsync()
{
    Console.WriteLine("開始工作");
    await Task.Delay(1000); // 模擬耗時(shí)操作
    Console.WriteLine("工作完成");
}

當(dāng)執(zhí)行到await Task.Delay(1000)時(shí):

  1. 檢查Task.Delay(1000)是否已完成。

  2. 如果未完成:

    • 創(chuàng)建一個(gè)continuation(后續(xù)操作),包含`await`之后的代碼。

    • 將這個(gè)continuation注冊(cè)到Task上。

    • 返回控制權(quán)給調(diào)用者。

  3. 當(dāng)Task.Delay(1000)完成時(shí):

    • 觸發(fā)注冊(cè)的continuation。

    • 恢復(fù)執(zhí)行`await`之后的代碼。

6. 異步方法的執(zhí)行流程

讓我們通過一個(gè)更復(fù)雜的例子來理解異步方法的執(zhí)行流程:

static async Task Main(string[] args)
{
    await MainMethodAsync();
    Console.ReadKey();
}

public static async Task MainMethodAsync()
{
    Console.WriteLine("1. 開始主方法");
    await Method1Async();
    Console.WriteLine("4. 主方法結(jié)束");
}

public static async Task Method1Async()
{
    Console.WriteLine("2. 開始方法1");
    await Task.Delay(1000);
    Console.WriteLine("3. 方法1結(jié)束");
}

執(zhí)行流程如下:

  1. MainMethodAsync開始執(zhí)行,打印"1. 開始主方法"。

  2. 遇到await Method1Async(),進(jìn)入Method1Async。

  3. Method1Async打印"2. 開始方法1"。

  4. 遇到await Task.Delay(1000),注冊(cè)continuation并返回。

  5. 控制權(quán)回到MainMethodAsync,但因?yàn)?code style="-webkit-tap-highlight-color: transparent; margin: 0px 2px; padding: 2px 4px; outline: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; font-size: inherit; color: rgb(233, 105, 0); line-height: inherit; border-radius: 4px; background: rgb(248, 248, 248);">Method1Async未完成,所以MainMethodAsync也返回。

  6. 1秒后,Task.Delay完成,觸發(fā)continuation。

  7. Method1Async繼續(xù)執(zhí)行,打印"3. 方法1結(jié)束"。

  8. Method1Async完成,觸發(fā)MainMethodAsync的continuation。

  9. MainMethodAsync繼續(xù)執(zhí)行,打印"4. 主方法結(jié)束"。

7. 異常處理

async/await模式下的異常處理非常直觀。你可以使用常規(guī)的try/catch塊,異步方法中拋出的異常會(huì)被封裝在返回的Task中,并在await時(shí)重新拋出。

8. 避免常見陷阱

使用async/await時(shí),有一些常見的陷阱需要注意:

8.1 死鎖

考慮以下代碼:

public async Task DeadlockDemoAsync()
{
    await Task.Delay(1000).ConfigureAwait(false);
}

public void CallAsyncMethod()
{
    DeadlockDemoAsync().Wait(); // 可能導(dǎo)致死鎖
}
  • 當(dāng)在UI線程(或任何有同步上下文的線程)中調(diào)用CallAsyncMethod()時(shí),會(huì)發(fā)生死鎖。

  • Wait()方法會(huì)阻塞當(dāng)前線程,等待異步操作完成。

  • 當(dāng)異步操作完成時(shí),它默認(rèn)會(huì)嘗試在原始的同步上下文(通常是UI線程)上繼續(xù)執(zhí)行。

  • 但是原始線程已經(jīng)被Wait()阻塞了,導(dǎo)致死鎖。

8.2 忘記await

public async Task ForgetAwaitDemoAsync()
{
    DoSomethingAsync(); // 忘記await
    Console.WriteLine("完成"); // 這行可能在異步操作完成之前執(zhí)行
}

始終記得在異步方法調(diào)用前使用await。

8.3 過度使用async void

除了事件處理程序外,應(yīng)避免使用async void方法,因?yàn)樗鼈兊漠惓ky以捕獲和處理。

public async void BadAsyncVoidMethod()
{
    await Task.Delay(1000);
    throw new Exception("這個(gè)異常很難被捕獲");
}

9. 高級(jí)模式

9.1 并行執(zhí)行多個(gè)任務(wù)

使用Task.WhenAll可以并行執(zhí)行多個(gè)異步任務(wù):

public async Task ParallelExecutionDemo()
{
    var task1 = DoWorkAsync(1);
    var task2 = DoWorkAsync(2);
    var task3 = DoWorkAsync(3);

    await Task.WhenAll(task1, task2, task3);
    Console.WriteLine("所有任務(wù)完成");
}

public async Task DoWorkAsync(int id)
{
    await Task.Delay(1000);
    Console.WriteLine($"任務(wù) {id} 完成");
}

9.2 帶超時(shí)的異步操作

使用Task.WhenAnyTask.Delay可以實(shí)現(xiàn)帶超時(shí)的異步操作:

static async Task Main(string[] args)
{
    await FetchDataWithTimeoutAsync("http://www.google.com",new TimeSpan(003));
    Console.ReadKey();
}

static async Task<string> FetchDataWithTimeoutAsync(string url, TimeSpan timeout)
{
    using (var client = new HttpClient())
    {
        var dataTask = client.GetStringAsync(url);
        var timeoutTask = Task.Delay(timeout);

        var completedTask = await Task.WhenAny(dataTask, timeoutTask);
        if (completedTask == timeoutTask)
        {
            throw new TimeoutException("操作超時(shí)");
        }

        return await dataTask;
    }
}

10. 結(jié)論

asyncawait極大地簡化了C#中的異步編程,使得編寫高效、響應(yīng)式的應(yīng)用程序變得更加容易。通過將復(fù)雜的異步操作轉(zhuǎn)換為看似同步的代碼,它們提高了代碼的可讀性和可維護(hù)性。


該文章在 2024/12/9 18:38:49 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲(chǔ)管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved