多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# async(C# 参考) 使用 **async** 修饰符可将方法、[lambda 表达式](https://msdn.microsoft.com/zh-CN/library/bb397687.aspx)或[匿名方法](https://msdn.microsoft.com/zh-CN/library/0yw3tz5k.aspx)指定为异步。如果对方法或表达式使用此修饰符,则其称为异步方法。 ``` public async Task<int> ExampleMethodAsync() { // . . . . } ``` 如果你不熟悉异步编程或不了解异步方法如何使用 **await** 关键字来完成可能需要长时间运行的工作而不阻止调用方的线程,则应阅读[使用 Async 和 Await 的异步编程(C# 和 Visual Basic)](https://msdn.microsoft.com/zh-CN/library/hh191443.aspx)中的简介。 ``` string contents = await contentsTask; ``` 方法将同步运行,直至到达其第一个 **await** 表达式,此时会将方法挂起,直到等待的任务完成。同时,如下节示例中所示,控件将返回到方法的调用方。 如果 **async** 关键字修改的方法不包含 **await** 表达式或语句,则该方法将同步执行。编译器警告将通知你不包含 **await** 的任何异步方法,因为该情况可能表示存在错误。请参见[编译器警告(等级 1)CS4014](https://msdn.microsoft.com/zh-CN/library/hh873131.aspx)。 **async** 关键字是上下文关键字,原因在于只有当它修饰方法、lambda 表达式或匿名方法时,它才是关键字。在所有其他上下文中,都会将其解释为标识符。 ## 示例 下面的示例展示了异步事件处理程序 StartButton_Click 和异步方法 ExampleMethodAsync 之间的控制结构和流程。此异步方法得到的结果是一个下载网站的长度。此代码适用于在 Visual Studio 2013 中创建的 Windows Presentation Foundation (WPF) 应用或 Windows 应用商店应用;请参见有关设置应用的代码注释。 ``` // You can run this code in Visual Studio 2013 as a WPF app or a Windows Store app. // You need a button (StartButton) and a textbox (ResultsTextBox). // Remember to set the names and handler so that you have something like this: // <Button Content="Button" HorizontalAlignment="Left" Margin="88,77,0,0" VerticalAlignment="Top" Width="75" // Click="StartButton_Click" Name="StartButton"/> // <TextBox HorizontalAlignment="Left" Height="137" Margin="88,140,0,0" TextWrapping="Wrap" // Text="TextBox" VerticalAlignment="Top" Width="310" Name="ResultsTextBox"/> // To run the code as a WPF app: // paste this code into the MainWindow class in MainWindow.xaml.cs, // add a reference to System.Net.Http, and // add a using directive for System.Net.Http. // To run the code as a Windows Store app: // paste this code into the MainPage class in MainPage.xaml.cs, and // add using directives for System.Net.Http and System.Threading.Tasks. private async void StartButton_Click(object sender, RoutedEventArgs e) { // ExampleMethodAsync returns a Task<int>, which means that the method // eventually produces an int result. However, ExampleMethodAsync returns // the Task<int> value as soon as it reaches an await. ResultsTextBox.Text += "\n"; try { int length = await ExampleMethodAsync(); // Note that you could put "await ExampleMethodAsync()" in the next line where // "length" is, but due to when '+=' fetches the value of ResultsTextBox, you // would not see the global side effect of ExampleMethodAsync setting the text. ResultsTextBox.Text += String.Format("Length: {0}\n", length); } catch (Exception) { // Process the exception if one occurs. } } public async Task<int> ExampleMethodAsync() { var httpClient = new HttpClient(); int exampleInt = (await httpClient.GetStringAsync("http://msdn.microsoft.com")).Length; ResultsTextBox.Text += "Preparing to finish ExampleMethodAsync.\n"; // After the following return statement, any method that's awaiting // ExampleMethodAsync (in this case, StartButton_Click) can get the // integer result. return exampleInt; } // Output: // Preparing to finish ExampleMethodAsync. // Length: 53292 ``` | ![System_CAPS_important](https://box.kancloud.cn/2016-01-31_56adb62ec9ef4.jpeg)重要事项 | | :-- | | 有关各项任务以及在等待任务期间所执行代码的更多信息,请参见[使用 Async 和 Await 的异步编程(C# 和 Visual Basic)](https://msdn.microsoft.com/zh-CN/library/hh191443.aspx)。有关使用类似元素的完整 WPF 示例,请参见[演练:使用 Async 和 Await 访问 Web(C# 和 Visual Basic)](https://msdn.microsoft.com/zh-CN/library/hh300224.aspx)。你可以从[开发人员代码示例](http://go.microsoft.com/fwlink/?LinkId=255191)下载演练代码。 | ## 返回类型 异步方法的返回类型可以为 [Task](https://msdn.microsoft.com/zh-CN/library/system.threading.tasks.task.aspx)、[Task&lt;TResult&gt;](https://msdn.microsoft.com/zh-CN/library/dd321424.aspx) 或 [void](https://msdn.microsoft.com/zh-CN/library/yah0tteb.aspx)。方法不能声明任何 [ref](https://msdn.microsoft.com/zh-CN/library/14akc2c7.aspx) 或 [out](https://msdn.microsoft.com/zh-CN/library/t3c3bfhx.aspx) 参数,但是可以调用具有这类参数的方法。 如果异步方法的[返回](https://msdn.microsoft.com/zh-CN/library/1h3swy84.aspx)语句指定一个 **TResult** 类型的操作数,则你应指定 **Task&lt;TResult&gt;** 作为方法的返回类型。如果当方法完成时未返回有意义的值,则应使用 **Task**。即,对方法的调用将返回一个 **Task**,但是当 **Task** 完成时,任何等待 **Task** 的所有 **await** 表达式的计算结果都为 **void**。 你应主要使用 **void** 返回类型来定义事件处理程序,这些处理程序需要此返回类型。 **void** 返回异步方法的调用方不能等待,并且无法捕获该方法引发的异常。 有关更多信息和示例,请参见[异步返回类型(C# 和 Visual Basic)](https://msdn.microsoft.com/zh-CN/library/hh524395.aspx)。 ## 请参阅 [AsyncStateMachineAttribute](https://msdn.microsoft.com/zh-CN/library/system.runtime.compilerservices.asyncstatemachineattribute.aspx) [await(C# 参考)](https://msdn.microsoft.com/zh-CN/library/hh156528.aspx) [演练:使用 Async 和 Await 访问 Web(C# 和 Visual Basic)](https://msdn.microsoft.com/zh-CN/library/hh300224.aspx) [使用 Async 和 Await 的异步编程(C# 和 Visual Basic)](https://msdn.microsoft.com/zh-CN/library/hh191443.aspx)