基于任务的异步编程模式,Task-based Asynchronous Pattern

术语:

APM           异步编程模型,Asynchronous Programming Model,其中异步操作由一对 Begin/End 方法(如 FileStream.BeginRead 和Stream.EndRead)表示。

EAP           基于事件的异步编程模式,Event-based Asynchronous Pattern,其中异步操作由名为OperationNameAsync 和 OperationNameCompleted 的方法/事件对(如WebClient.DownloadStringAsync 和 WebClient.DownloadStringCompleted)表示。 (EAP 是在 .NET Framework 2.0 版本中引入的。)

任务并行库 (TPL) 可采用各种方法与任一异步模式协同使用。 可将 APM 和 EAP 操作作为任务向库使用者公开,也可以公开 APM 模式但用 Task 对象在内部实现它们。

async 和 await 关键字是在 Visual Studio 2012 中引入的,是异步编程的核心。 通过使用这两个关键字,你可以使用 .NET framework 或 Windows 运行时中的资源轻松创建异步方法。

什么是异步方法?

使用 async 修饰符定义并且通常包含一个或多个 await 表达式的这类方法称为异步方法

注意:

await 表达式只能在由 async 修饰符标记的立即封闭方法体、lambda 表达式或异步方法中出现

await 表达式不阻止正在执行它的线程。而是使编译器将剩下的异步方法注册为等待任务的延续任务。控制权随后会返回给异步方法的调用方。任务完成时,它会调用其延续任务,异步方法的执行会在暂停的位置处恢复。

async 和 await 关键字不会导致创建其他线程 因为异步方法不会在其自身线程上运行,因此它不需要多线程

以下特征总结了成为异步方法的原因。

  • 方法签名包含一个 Async 或 async 修饰符。

  • 按照约定,异步方法的名称以“Async”后缀为结尾。

  • 返回类型为下列类型之一:

    • 如果你的方法有操作数为 TResult 类型的返回语句,则为 Task<TResult>

    • 如果你的方法没有返回语句或具有没有操作数的返回语句,则为 Task

    • 如果你编写的是异步事件处理程序,则为 Void(Visual Basic 中为 Sub)。

  • 方法通常包含至少一个 await 表达式,该表达式标记一个点,在该点上,直到等待的异步操作完成方法才能继续。 同时,将方法挂起,并且控件返回到方法的调用方。 本主题的下一节将解释悬挂点发生的情况。

 异步方法示例:

private async Task SumPageSizesAsync()
        {
            // Declare an HttpClient object and increase the buffer size. The
            // default buffer size is 65,536.
            HttpClient client =
                new HttpClient() { MaxResponseContentBufferSize = 1000000 };

            // Make a list of web addresses.
            List<string> urlList = SetUpURLList();

            var total = 0;

            foreach (var url in urlList)
            {
                // GetByteArrayAsync returns a task. At completion, the task
                // produces a byte array.
                byte[] urlContents = await client.GetByteArrayAsync(url);               

                // The following two lines can replace the previous assignment statement.
                //Task<byte[]> getContentsTask = client.GetByteArrayAsync(url);
                //byte[] urlContents = await getContentsTask;

                DisplayResults(url, urlContents);

                // Update the total.
                total += urlContents.Length;
            }

            // Display the total count for all of the websites.
            resultsTextBox.Text +=
                string.Format("

Total bytes returned:  {0}
", total);
        }

异步方法的调用

标记的异步方法可以使用 Await 或 await 来指定悬挂点。 await 运算符通知编译器异步方法只有直到等待的异步过程完成才能继续通过该点。 同时,控件返回至异步方法的调用方

异步方法调用未使用 await 运算符标记悬挂点,则该方法将作为同步方法执行,不管异步修饰符如何

使用 Async 和 Await 的异步编程:https://msdn.microsoft.com/zh-cn/library/hh191443.aspx

原文地址:https://www.cnblogs.com/imust2008/p/5534371.html