为什么要在方法中间等待异步方法?

问题描述:

我发现这个例子在书中使用async/await东西。可以请别人告诉我等待下面例子中的异步方法有什么好处?为什么要在方法中间等待异步方法?

using (SqlConnection connection = new SqlConnection(connectionString)) 
{ 
    SqlCommand command = new SqlCommand("SELECT * FROM People", connection); 
    await connection.OpenAsync(); 
    SqlDataReader dataReader = **await** command.ExecuteReaderAsync(); 
    while (**await** dataReader.ReadAsync()) 
    { 
    string formatStringWithMiddleName = "Person ({0}) is named {1} {2} {3}"; 
    string formatStringWithoutMiddleName = "Person ({0}) is named {1} {3}"; 
    if ((dataReader["middlename"] == null)) 
    { 
     Console.WriteLine(formatStringWithoutMiddleName, 
     dataReader["id"], 
     dataReader["firstname"], 
     dataReader["lastname"]); 
    } 
    else 
    { 
     Console.WriteLine(formatStringWithMiddleName, 
     dataReader["id"], 
     dataReader["firstname"], 
     dataReader["middlename"], 
     dataReader["lastname"]); 
    } 
    } 
    dataReader.Close(); 
    } 
} 

我只是不能换我的头解决这个问题。按照我的理解,等待块被调用(在这种情况下,ExecuteReaderAsync和ReadAsync)返回。调用异步方法并在代码中间立即阻塞的意义何在?在调用异步方法和返回调用方的结果之间没有实际执行任何操作? 它比单纯做这个更快或更有效率?

....

SqlDataReader dataReader = command.ExecuteReader(); 
     while (dataReader.Read()) 
     { 
      ..... 
+1

通过等待异步方法完成,它们可以像处理同步代码一样处理异步代码。这在很长一段时间里一直是软件开发中的一个问题,作者选择处理这个问题的方式就是其中之一。这不是我喜欢的方式,但这个例子也可能很古老。 – deltree

我明白的方式,等待阻塞,直到调用的方法(在此情况下,ExecuteReaderAsync和ReadAsync)返回。

否; await暂停该方法和返回给调用者。因此,而不是ReadAsync操作的持续时间内阻止调用线程。

概念上,它是同步系列之间的差异。同步意味着阻塞:方法调用将停止线程,直到Read完成。串行意味着一次一个:该方法将暂停执行,直至ReadAsync完成。所以,常见的await *Async()模式是串行的,但是采用异步方式,而不是同步方式。

有关asyncawait的更多信息,请参阅我的async intro后。

+0

Btw是我唯一认为“等待”上下文关键字是不好的选择吗?我想不出一个更好的变体。 –

+1

@ Sergey.quixoticaxis.Ivanov:我有一篇博客文章,是关于为什么'async'和'await'关键字按照他们的方式设计的非正式问答(http://blog.stephencleary.com/ 2011/09 /异步-CTP-为什么-DO - 关键词工作是-way.html)。 –

+0

有趣的帖子,谢谢。虽然它大多描述了“等待”背后的语言推理,但不是选择“等待”而不是“离开”或“离开”(同时保留语义)的语言理由。 –

这会暂时阻止您的方法,但会保持UI线程的响应。内部C#重写该方法。 await之后的部分被转换为一种回调方法(不是很好,但你可以想象它是)。该方法立即在await处返回,并在异步操作完成时恢复其中止的地方。