共用方式為


使用 Async 和 Await 設計非同步程式 (C# 和 Visual Basic)

您可以使用非同步程式設計,避免發生效能瓶頸並增強應用程式的整體回應性。 不過,撰寫非同步應用程式的傳統技術可能很複雜,因而難以撰寫、偵錯和維護。

Visual Studio 2012 推出了更簡單的方法,也就是非同步程式設計,充分運用了 .NET Framework 4.5 和 Windows 執行階段中的非同步支援。 編譯器會代替開發人員處理過去經常要處理的困難工作,而您的應用程式仍保有類似同步程式碼的邏輯結構。 因此,您可以輕鬆擁有非同步程式設計的所有優點。

本主題包含下列章節。

  • Async 改善回應
  • 非同步方法比較容易撰寫
  • 非同步方法中執行了哪些工作
  • 應用程式開發介面非同步方法
  • 執行緒
  • Async 和 Await
  • 傳回類型和參數
  • 命名規範
  • 相關主題
  • 完整範例
  • 相關主題

本主題提供使用非同步程式設計的時機和使用方式的概觀,並加入包含詳細資料及範例的支援主題連結。

Async 改善回應

非同步對於可能在像是應用程式存取 Web 時會進行封鎖的活動而言相當重要。 存取 Web 資源的速度有時會變慢或延遲。 如果這類活動在同步處理序中遭到封鎖,整個應用程式就必須等候。 在非同步處理序中,應用程式可以繼續處理其他與 Web 資源不相關的工作,直到可能的封鎖工作完成。

下表顯示非同步程式設計一般會改善回應速度的部分。 所列出來自 .NET Framework 4.5 和 Windows 執行階段的 API 包含支援非同步程式設計的方法。

應用程式區域

包含非同步方法的支援 API

Web 存取

HttpClientSyndicationClient

處理檔案

StorageFileStreamWriterStreamReaderXmlReader

處理影像

MediaCaptureBitmapEncoderBitmapDecoder

WCF 程式設計

同步和非同步作業

非同步對於存取 UI 執行緒的應用程式而言確實特別有用,因為所有 UI 相關活動通常都會共用一個執行緒。 如果同步應用程式中有任何處理序遭到封鎖,所有處理序都會遭到封鎖。 您的應用程式會停止回應,而且您可能會認為應用程式失敗,但實際上只是在等候。

當您使用非同步方法時,應用程式會繼續回應 UI。 例如,您可以調整視窗大小或將視窗縮到最小,如果不想要等待應用程式完成,也可以將它關閉。

非同步方法會在設計非同步作業時,於選項清單中加入自動傳輸的對等項目讓您選擇。 也就是說,除了擁有傳統非同步程式設計的所有優點之外,開發人員所需投入的時間也大為減少。

非同步方法比較容易撰寫

Visual Basic 中的 AsyncAwait 關鍵字,以及 C# 中的 asyncawait 關鍵字,都是非同步程式設計的核心。 您可以使用這兩個關鍵字,在 .NET Framework 或 Windows 執行階段中使用資源來建立非同步方法,幾乎就像建立同步方法一樣容易。 使用 async 和 await 定義的非同步方法就稱為非同步方法。

下列範例將示範非同步方法。 程式碼中的一切對您而言應該幾乎完全熟悉。 註解會標註您加入以建立非同步的功能。

您可以在本主題最後找到完整的範例檔案,並且可以從非同步範例:<使用 Async 和 Await 進行非同步程式設計>中的範例下載範例。

' Three things to note in the signature: 
'  - The method has an Async modifier.  
'  - The return type is Task or Task(Of T). (See "Return Types" section.) 
'    Here, it is Task(Of Integer) because the return statement returns an integer. 
'  - The method name ends in "Async."
Async Function AccessTheWebAsync() As Task(Of Integer)

    ' You need to add a reference to System.Net.Http to declare client. 
    Dim client As HttpClient = New HttpClient()

    ' GetStringAsync returns a Task(Of String). That means that when you await the 
    ' task you'll get a string (urlContents). 
    Dim getStringTask As Task(Of String) = client.GetStringAsync("https://msdn.microsoft.com")


    ' You can do work here that doesn't rely on the string from GetStringAsync.
    DoIndependentWork()

    ' The Await operator suspends AccessTheWebAsync. 
    '  - AccessTheWebAsync can't continue until getStringTask is complete. 
    '  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
    '  - Control resumes here when getStringTask is complete.  
    '  - The Await operator then retrieves the string result from getStringTask. 
    Dim urlContents As String = Await getStringTask

    ' The return statement specifies an integer result. 
    ' Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
    Return urlContents.Length
End Function
// Three things to note in the signature: 
//  - The method has an async modifier.  
//  - The return type is Task or Task<T>. (See "Return Types" section.)
//    Here, it is Task<int> because the return statement returns an integer. 
//  - The method name ends in "Async."
async Task<int> AccessTheWebAsync()
{ 
    // You need to add a reference to System.Net.Http to declare client.
    HttpClient client = new HttpClient();

    // GetStringAsync returns a Task<string>. That means that when you await the 
    // task you'll get a string (urlContents).
    Task<string> getStringTask = client.GetStringAsync("https://msdn.microsoft.com");

    // You can do work here that doesn't rely on the string from GetStringAsync.
    DoIndependentWork();

    // The await operator suspends AccessTheWebAsync. 
    //  - AccessTheWebAsync can't continue until getStringTask is complete. 
    //  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
    //  - Control resumes here when getStringTask is complete.  
    //  - The await operator then retrieves the string result from getStringTask. 
    string urlContents = await getStringTask;

    // The return statement specifies an integer result. 
    // Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
    return urlContents.Length;
}

如果 AccessTheWebAsync 在呼叫 GetStringAsync 與等候其完成之間沒有任何可以執行的工作,您可以在下列單一陳述式中呼叫和等候,以簡化程式碼。

Dim urlContents As String = Await client.GetStringAsync()
string urlContents = await client.GetStringAsync();

下列特性摘要說明上述範例為非同步方法的原因。

  • 方法簽章包含 Async 或 async 修飾詞。

  • 按照慣例,非同步方法的名稱是以 "Async" 後置字元為結尾。

  • 傳回類型是下列其中一種類型:

    • 如果方法的 return 陳述式中運算元的類型為 TResult,則為 Task

    • 如果方法沒有 return 陳述式或是 return 陳述式沒有運算元,則為 Task

    • 如果您撰寫非同步事件處理常式,則為 void (在 Visual Basic 中為 Sub)。

    如需詳細資訊,請參閱本主題後段的<傳回類型和參數>。

  • 方法通常至少包含一個 await 運算式,表示方法在等候的非同步作業完成後才能繼續的點。 此時,方法已暫停,而且控制權返回到方法的呼叫端。 本主題的下一節將說明暫停點會發生什麼情況。

在非同步方法中,您會使用提供的關鍵字和類型表示您想要執行的工作,而編譯器會完成其餘的部分,包括追蹤控制權返回已暫停方法中的等候點時必須進行的作業。 某些常式處理序像是迴圈和例外狀況處理,在傳統非同步程式碼中可能不容易處理。 在非同步方法中,您可以像在同步方案中一樣撰寫這些項目,如此就可以解決這個問題了。

如需舊版 .NET Framework 中非同步的詳細資訊,請參閱 TPL 和傳統 .NET Framework 非同步程式設計

非同步方法中執行了哪些工作

在非同步程式設計中要了解的最重要事情,就是控制流程如何在方法之間移動。 下圖將引導您了解整個程序。

追蹤非同步程式

圖中的數字對應下列步驟。

  1. 事件處理常式會呼叫並等候 AccessTheWebAsync 非同步方法。

  2. AccessTheWebAsync 會建立 HttpClient 執行個體並呼叫 GetStringAsync 非同步方法,將網站的內容當做字串下載。

  3. GetStringAsync 中發生了導致進度暫停的一些狀況。 可能必須等待網站下載或其他封鎖活動。 為了避免封鎖資源,GetStringAsync 會將控制權遞交 (Yield) 給它的呼叫端 AccessTheWebAsync。

    GetStringAsync 會傳回 Task (其中 TResult 是字串),而 AccessTheWebAsync 則會將工作指派給 getStringTask 變數。 工作代表對 GetStringAsync 之呼叫的進行中程序,並承諾會在工作完成時產生實際字串值。

  4. 因為尚未等候 getStringTask,所以 AccessTheWebAsync 可以繼續進行其他不相依於 GetStringAsync 之最終結果的其他工作。 這項工作是由對同步方法 DoIndependentWork 的呼叫來表示。

  5. DoIndependentWork 是完成其工作並傳回其呼叫端的同步方法。

  6. AccessTheWebAsync 已完成所有可處理的工作,但未取得來自 getStringTask 的結果。 AccessTheWebAsync 接著要計算和傳回下載字串的長度,但是方法必須等到有字串時才能計算該值。

    因此,AccessTheWebAsync 會使用 await 運算子暫停其進度,並將控制權遞交 (Yield) 給呼叫 AccessTheWebAsync 的方法。 AccessTheWebAsync 會將 Task(Of Integer) 或 Task<int> 傳回至呼叫端。 這項工作代表承諾會產生相當於下載字串長度的整數結果。

    注意事項注意事項

    如果 GetStringAsync (和 getStringTask) 在 AccessTheWebAsync 等候它之前先完成,控制權仍會留在 AccessTheWebAsync。如果呼叫的非同步處理序 (getStringTask) 已完成,而 AccessTheWebSync 無需等候最終結果時,那麼暫停然後再返回 AccessTheWebAsync 就是不必要的。

    在呼叫端 (在這個範例中是事件處理常式) 內,處理模式會持續進行。 呼叫端可能會在等候結果之前執行其他不取決於 AccessTheWebAsync 之結果的工作,或者呼叫端可能立即等候。事件處理常式會等候 AccessTheWebAsync,而 AccessTheWebAsync 會等候 GetStringAsync。

  7. GetStringAsync 完成並產生字串結果。 字串結果不會依照您預期的方式透過呼叫 GetStringAsync 來傳回 (請記住,方法已在步驟 3 傳回工作)。字串結果會改為儲存在表示方法 getStringTask 完成的工作中。 await 運算子會從 getStringTask 擷取結果。 指派陳述式會將擷取的結果指派給 urlContents。

  8. 當 AccessTheWebAsync 擁有字串結果時,方法就可以計算字串的長度。 然後 AccessTheWebAsync 的工作也已完成,而且等候事件處理常式可以繼續執行。 在本主題最後的完整範例中,您可以確認事件處理常式會擷取並列印長度結果的值。

如果您不熟悉非同步程式設計,請花一分鐘思考同步和非同步行為之間的差異。 同步方法會在其工作完成時傳回 (步驟 5),而非同步方法則會在其工作暫停時傳回工作值 (步驟 3 和步驟 6)。 當非同步方法最後完成其工作時,工作會標示為已完成,而結果 (如果有的話) 會儲存在工作中。

如需控制流程的詳細資訊,請參閱非同步程式中的控制流程 (C# 和 Visual Basic)

應用程式開發介面非同步方法

您可能會想知道哪裡可以找到支援非同步程式設計的方法,例如 GetStringAsync。 .NET Framework 4.5 包含許多可搭配 async 和 await 一起使用的成員。 您也可以藉由附加至成員名稱的 "Async" 後置字元和傳回類型 TaskTask 辨認這些成員。 例如,相對於同步方法 CopyToReadWrite,System.IO.Stream 類別也包含了一些方法,例如 CopyToAsyncReadAsyncWriteAsync

Windows 執行階段同樣包含許多可在 Windows 市集應用程式中搭配 async 和 await 使用的方法。 如需詳細資訊和範例方法,請參閱快速入門:在 C# 或 Visual Basic 中呼叫非同步 API非同步程式設計 (Windows 市集應用程式)WhenAny:銜接 .NET Framework 和 Windows 執行階段 (C# 和 Visual Basic)

執行緒

非同步方法主要做為非封鎖作業使用。 當等候的工作正在執行時,非同步方法的 await 運算式不會封鎖目前的執行緒。 運算式會改為註冊方法的其餘部分做為接續,並將控制權交還給非同步方法的呼叫端。

async 和 await 關鍵字不會導致建立其他執行緒。 由於非同步方法不會在本身的執行緒上執行,因此非同步方法不需要多執行緒。 方法會在目前的同步處理內容執行,而且只有在方法為作用中時才會在執行緒上花費時間。 您可以使用 Task.Run 將受限於 CPU 的工作移到背景執行緒,但是背景執行緒無法協助處理正在等待結果產生的處理序。

非同步程式設計的非同步方法幾乎是所有案例的現有方法當中較好的方法。 特別是,這個方法比受限於 IO 之作業的 BackgroundWorker 還要好,因為程式碼較簡單,而且不需要防範競爭情況。 與 Task.Run 結合時,非同步程式設計會比受限於 CPU 之作業的 BackgroundWorker 還要好,因為非同步程式設計會將執行程式碼的協調工作細節,從 Task.Run 傳輸至執行緒集區的工作中分出來。

Async 和 Await

如果您使用 Asyncasync 修飾詞將方法指定為非同步方法,就會啟用下列兩項功能。

  • 標記的非同步方法可以使用 Awaitawait 來指定暫停點。 await 運算子會告知編譯器,非同步方法只有在等候的非同步處理序完成後,才能繼續通過該點。 同時,控制權會返回非同步方法的呼叫端。

    非同步方法在 await 運算式上暫停時,並不構成從方法退出,而且 finally 區塊也不會執行。

  • 標記的非同步方法本身可以做為其呼叫方法的等候目標。

非同步方法通常包含一個或多個 await 運算子,但是沒有 await 運算式也不會造成編譯器錯誤。 如果非同步方法不使用 await 運算子標記暫停點,則方法會無視於 async 修飾詞,像同步方法一樣執行。 編譯器將對這類方法發出警告。

Async、async、Await 和 await 是內容關鍵字。 如需詳細資訊和範例,請參閱下列主題:

傳回類型和參數

在 .NET Framework 程式設計中,非同步方法通常會傳回 TaskTask。 在非同步方法內,await 運算子會套用至呼叫另一個非同步方法所傳回的工作。

如果方法包含指定 TResult 類型運算元的 Return (Visual Basic) 或 return (C#) 陳述式,請指定 Task 做為傳回類型。

如果方法沒有 return 陳述式,或者方法的 return 陳述式不會傳回運算元,請使用 Task 做為傳回類型。

下列範例將示範如何宣告和呼叫會傳回 TaskTask 的方法。

' Signature specifies Task(Of Integer)
Async Function TaskOfTResult_MethodAsync() As Task(Of Integer)

    Dim hours As Integer
    ' . . .
    ' Return statement specifies an integer result.
    Return hours
End Function

' Calls to TaskOfTResult_MethodAsync
Dim returnedTaskTResult As Task(Of Integer) = TaskOfTResult_MethodAsync()
Dim intResult As Integer = Await returnedTaskTResult
' or, in a single statement
Dim intResult As Integer = Await TaskOfTResult_MethodAsync()


' Signature specifies Task
Async Function Task_MethodAsync() As Task

    ' . . .
    ' The method has no return statement.
End Function

' Calls to Task_MethodAsync
Task returnedTask = Task_MethodAsync()
Await returnedTask
' or, in a single statement
Await Task_MethodAsync()
// Signature specifies Task<TResult>
async Task<int> TaskOfTResult_MethodAsync()
{
    int hours;
    // . . .
    // Return statement specifies an integer result.
    return hours;
}

// Calls to TaskOfTResult_MethodAsync
Task<int> returnedTaskTResult = TaskOfTResult_MethodAsync();
int intResult = await returnedTaskTResult;
// or, in a single statement
int intResult = await TaskOfTResult_MethodAsync();


// Signature specifies Task
async Task Task_MethodAsync()
{
    // . . .
    // The method has no return statement.  
}

// Calls to Task_MethodAsync
Task returnedTask = Task_MethodAsync();
await returnedTask;
// or, in a single statement
await Task_MethodAsync();

每項傳回的工作都代表進行中的工作。 工作會封裝這個非同步處理序狀態的相關資訊,以及處理序的最終結果,或是處理序不成功時,則會封裝處理序引發的例外狀況。

非同步方法也可以是 Sub 方法 (Visual Basic) 或具有 void 傳回類型 (C#)。 這個傳回類型主要用於定義需要 void 傳回類型的事件處理常式。 非同步事件處理常式通常做為非同步程式的起點。

本身為 Sub 程序或具有 void 傳回類型的非同步方法無法等候,而且 void 傳回方法的呼叫端無法攔截方法擲回的任何例外狀況。

非同步方法不可以宣告為 Visual Basic 中的 ByRef 參數或是 C# 中的 refout 參數,但是方法可以呼叫具有這類參數的方法。

如需詳細資訊與範例,請參閱非同步方法的傳回類型 (C# and Visual Basic)。 如需如何攔截非同步方法中例外狀況的詳細資訊,請參閱 try-catch (C# 參考)Try...Catch...Finally 陳述式 (Visual Basic)

Windows 執行階段程式設計中的非同步應用程式開發介面有下列其中一種傳回類型,類似於工作:

如需詳細資訊和範例,請參閱快速入門:在 C# 或 Visual Basic 中呼叫非同步 API

命名規範

依照慣例,您會將 "Async" 附加至具有 Async 或 async 修飾詞之方法的名稱。

當事件、基底類別或介面合約採用不同的名稱時,您可以忽略慣例。 例如,您不應該重新命名通用事件處理常式,像是 Button1_Click。

相關主題

標題

描述

範例

逐步解說:使用 Async 和 Await 存取 Web (C# 和 Visual Basic)

顯示如何將同步 WPF 方案轉換為非同步 WPF 方案。 應用程式會下載一系列的網站。

非同步範例:存取 Web 逐步解說 (C# 和 Visual Basic)

如何:使用 Task.WhenAll 擴充非同步逐步解說的內容 (C# 和 Visual Basic)

Task.WhenAll 加入至前一個逐步解說。 使用 WhenAll 會同時開始進行所有的下載。

如何:使用 Async 和 Await,同時發出多個 Web 要求 (C# 和 Visual Basic)

示範如何同時啟動數個工作。

非同步範例:平行進行多個 Web 要求 (C# 和 Visual Basic)

非同步方法的傳回類型 (C# and Visual Basic)

說明非同步方法可以傳回的類型,並解釋每種類型的適用時機。

非同步程式中的控制流程 (C# 和 Visual Basic)

在非同步程式中詳細追蹤一連串 await 運算式的控制流程。

非同步範例:非同步程式中的控制流程 (C# 和 Visual Basic)

微調非同步應用程式 (C# 和 Visual Basic)

顯示如何將下列功能加入至您的非同步方案:

非同步範例:微調應用程式 (C# 和 Visual Basic)

處理非同步應用程式中的重新進入 (C# 和 Visual Basic)

顯示如何處理現用非同步作業在執行當中重新啟動的情況。

WhenAny:銜接 .NET Framework 和 Windows 執行階段 (C# 和 Visual Basic)

顯示如何在 Windows 執行階段中,進行 .NET Framework 與 IAsyncOperations 的工作類型之間的橋接,讓您可以搭配 Windows 執行階段方法使用 WhenAny``1

非同步範例:在 .NET 和 Windows 執行階段之間進行橋接 (AsTask 和 WhenAny)

非同步取消作業:銜接 .NET Framework 和 Windows 執行階段 (C# 和 Visual Basic)

顯示如何在 Windows 執行階段中,進行 .NET Framework 與 IAsyncOperations 的工作類型之間的橋接,讓您可以搭配 Windows 執行階段方法使用 CancellationTokenSource

非同步範例:在 .NET 和 Windows 執行階段之間進行橋接 (AsTask & Cancellation)

使用非同步方式存取檔案 (C# 和 Visual Basic)

列出並示範使用 async 和 await 存取檔案的優點。

逐步解說:搭配非同步方法使用偵錯工具

示範在 await 陳述式的控制流程,並示範 [逐步執行]、[不進入函式] 和 [跳離函式] 命令在非同步方法中的行為。

以工作為基礎的非同步模式 (TAP)

描述 .NET Framework 中非同步的新模式。 這個模式是根據 TaskTask 類型。

快速入門:在 C# 或 Visual Basic 中呼叫非同步 API

示範如何在 Windows 市集應用程式中使用 async 和 await。

非同步程式設計 (Windows 市集應用程式)

提供 Windows 執行階段中非同步程式設計的概觀。

Channel 9 上的 Async 影片

提供有關非同步程式設計的各種不同視訊連結。

完整範例

下列程式碼是本主題討論之 Windows Presentation Foundation (WPF) 應用程式中的 MainWindow.xaml.vb 或 MainWindow.xaml.cs 檔案。 您可以從非同步範例:<使用 Async 和 Await 進行非同步程式設計>中的範例下載範例。

' Add an Imports statement and a reference for System.Net.Http 
Imports System.Net.Http

Class MainWindow

    ' Mark the event handler with async so you can use Await in it. 
    Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)

        ' Call and await separately. 
        'Task<int> getLengthTask = AccessTheWebAsync(); 
        '' You can do independent work here. 
        'int contentLength = await getLengthTask; 

        Dim contentLength As Integer = Await AccessTheWebAsync()

        ResultsTextBox.Text &=
            String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, contentLength)
    End Sub 


    ' Three things to note in the signature: 
    '  - The method has an Async modifier.  
    '  - The return type is Task or Task(Of T). (See "Return Types" section.) 
    '    Here, it is Task(Of Integer) because the return statement returns an integer. 
    '  - The method name ends in "Async."
    Async Function AccessTheWebAsync() As Task(Of Integer)

        ' You need to add a reference to System.Net.Http to declare client. 
        Dim client As HttpClient = New HttpClient()

        ' GetStringAsync returns a Task(Of String). That means that when you await the 
        ' task you'll get a string (urlContents). 
        Dim getStringTask As Task(Of String) = client.GetStringAsync("https://msdn.microsoft.com")


        ' You can do work here that doesn't rely on the string from GetStringAsync.
        DoIndependentWork()

        ' The Await operator suspends AccessTheWebAsync. 
        '  - AccessTheWebAsync can't continue until getStringTask is complete. 
        '  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
        '  - Control resumes here when getStringTask is complete.  
        '  - The Await operator then retrieves the string result from getStringTask. 
        Dim urlContents As String = Await getStringTask

        ' The return statement specifies an integer result. 
        ' Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
        Return urlContents.Length
    End Function 


    Sub DoIndependentWork()
        ResultsTextBox.Text &= "Working . . . . . . ." & vbCrLf
    End Sub 
End Class 

' Sample Output: 

' Working . . . . . . . 

' Length of the downloaded string: 41763.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

// Add a using directive and a reference for System.Net.Http; 
using System.Net.Http;

namespace AsyncFirstExample
{
    public partial class MainWindow : Window
    {
        // Mark the event handler with async so you can use await in it. 
        private async void StartButton_Click(object sender, RoutedEventArgs e)
        {
            // Call and await separately. 
            //Task<int> getLengthTask = AccessTheWebAsync(); 
            //// You can do independent work here. 
            //int contentLength = await getLengthTask; 

            int contentLength = await AccessTheWebAsync();

            resultsTextBox.Text +=
                String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
        }


        // Three things to note in the signature: 
        //  - The method has an async modifier.  
        //  - The return type is Task or Task<T>. (See "Return Types" section.)
        //    Here, it is Task<int> because the return statement returns an integer. 
        //  - The method name ends in "Async."
        async Task<int> AccessTheWebAsync()
        { 
            // You need to add a reference to System.Net.Http to declare client.
            HttpClient client = new HttpClient();

            // GetStringAsync returns a Task<string>. That means that when you await the 
            // task you'll get a string (urlContents).
            Task<string> getStringTask = client.GetStringAsync("https://msdn.microsoft.com");

            // You can do work here that doesn't rely on the string from GetStringAsync.
            DoIndependentWork();

            // The await operator suspends AccessTheWebAsync. 
            //  - AccessTheWebAsync can't continue until getStringTask is complete. 
            //  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
            //  - Control resumes here when getStringTask is complete.  
            //  - The await operator then retrieves the string result from getStringTask. 
            string urlContents = await getStringTask;

            // The return statement specifies an integer result. 
            // Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
            return urlContents.Length;
        }


        void DoIndependentWork()
        {
            resultsTextBox.Text += "Working . . . . . . .\r\n";
        }
    }
}

// Sample Output: 

// Working . . . . . . . 

// Length of the downloaded string: 41564.

請參閱

參考

async (C# 參考)

await (C# 參考)

Await 運算子 (Visual Basic)

Async (Visual Basic)

其他資源

範例:適用於 Windows 市集應用程式的 .NET 非同步程式設計

範例:製作 await WebClient

範例 (C#):如何將自訂物件集合儲存至本機存放區

範例 (Visual Basic):將集合儲存至應用程式儲存區