异步编程试图了解等待是如何工作的

问题描述 投票:-2回答:1

所以我正在学习一些基本的异步编程并遵循本教程:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/但是我得到的输出与我期望的不同。

这是我的代码:

private async void btn1_Click(object sender, EventArgs e)
{
   await TestAsync();
   Console.WriteLine("terminate");
}

private async Task TestAsync()
{
   string str = await Todo();
   await Task.Delay(500);  //added await operator as per FCin advice
   Console.WriteLine(str);
}

private async Task<string> Todo()
{
   await Task.Delay(3000); //added await operator as per FCin advice
   return "return from async task";
}

从单击btn1开始,将触发btn1_Click方法。首先,它将调用TestAsync()。由于TestAsync方法的第一行是等待异步方法,我的理解是此时await运算符应该挂起TestAsync并将控制权返回给TestAsync的调用者,即btn1_Click。这应该打印“终止”,然后程序应耐心等待TestAsync完成并最终打印“”从异步任务返回“。但是我得到的输出是相反的顺序,我试图理解为什么。

所以我修改了它,以便在btn1_Click方法中等待TestAsync。我也改变了线程睡眠到任务延迟,但我仍然得到相同的输出...

Edit2:我正在使用的代码作为示例

// 1. 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()  
{   
// 2. You need to add a reference to System.Net.Http to declare client.  
HttpClient client = new HttpClient();  

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

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

// 5. 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;  

// 6. The return statement specifies an integer result.  
// Any methods that are awaiting AccessTheWebAsync retrieve the length value.  
return urlContents.Length;  
} 
c# asynchronous async-await
1个回答
0
投票

await做它说的,它等待。当你点击await它没有去调用方法,它等到Todo完成。现在为什么要使用async/await等待?因为在等待期间,它会做其他工作。它可以让您的UI保持运行它处理来自消息队列的消息,例如单击按钮,绘制控件,计算光标是否命中任何突出显示控件的边界框等。

你的代码现在是完全同步的,因为你没有等待Task.Delay。您甚至可能会对每个未等待的方法发出警告。

以下是此代码的执行方式:

  1. 等待3000毫秒
  2. 返回“从异步任务返回”
  3. 等待500毫秒
  4. 打印“从异步任务返回”
  5. 打印“终止”

码:

private async void btn1_Click(object sender, EventArgs e)
{
   await TestAsync();
   Console.WriteLine("terminate");
}

private async Task TestAsync()
{
   string str = await Todo();
   await Task.Delay(500);
   Console.WriteLine(str);
}

private async Task<string> Todo()
{
   await Task.Delay(3000);
   return "return from async task";
}
© www.soinside.com 2019 - 2024. All rights reserved.