Jan*_*dan 1 .net c# asynchronous async-await
我最近一直在学习异步编程,我想我已经掌握了它.异步编程很简单,只允许我们的程序进行多任务处理.
混乱配备await和async编程,它似乎混淆我多一点,可能有人帮助回答一些我的顾虑?
我没有看到async关键字那么多,只是你想要一种方法让Visual Studio知道该方法可能await是某种东西,并允许它来警告你.如果它有一些其他特殊含义实际影响某些东西,有人可以解释一下吗?
移动到await,跟一个朋友,我被告知我有1周重大的事情错了之后,await不会阻止当前的方法,它只是执行留在该方法中的代码,并不会在自己时代的异步操作.
现在,我不确定这种情况经常发生,但是让我们说你有这样的代码.
Console.WriteLine("Started checking a players data.");
var player = await GetPlayerAsync();
foreach (var uPlayer in Players.Values) {
uPlayer.SendMessage("Checking another players data");
}
if (player.Username == "SomeUsername") {
ExecuteSomeOperation();
}
Console.WriteLine("Finished checking a players data.");
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我运行了一些异步代码GetPlayerAsync,如果我们深入到范围并且我们需要访问播放器会发生什么,但它还没有返回播放器呢?
如果它没有阻止该方法,它如何知道该玩家不是null,它是否做了一些魔法并等待我们如果我们到达那种情况,或者我们只是禁止自己编写这种方法并处理它我们自己.
Eri*_*ert 13
我最近一直在学习异步编程,我想我已经掌握了它.
我是该功能的设计者之一,我不觉得我甚至接近掌握它,你问的初级问题,并有一些非常,非常错误的想法,所以有一些傲慢怎么回事我疑似.
异步编程只是简单地允许我们的程序进行多任务处理.
假设你问"为什么有些物质硬而有些软?" 我回答说"物质是由原子排列的,有些原子排列很硬,有些是柔软的".虽然这无疑是正确的,但我希望你能够继续这种无益的不解释.
同样,你刚刚用另一个模糊的词"多任务"取代了模糊的"异步"一词.这是一个没有解释的解释,因为您还没有明确定义多任务的含义.
异步工作流无疑是关于执行多个任务.这就是为什么工作流程中的基本工作单元是Task<T>monad.异步工作流是通过构建它们之间的依赖关系图来组成多个任务的.但这并没有说明如何在软件中实现该工作流程.这是一个复杂而深刻的主题.
我没有看到async关键字那么多,只是你想方法让Visual Studio知道该方法可能等待某些东西并允许它警告你.
这基本上是正确的,但不要认为它是告诉Visual Studio; VS不在乎.这是你告诉的C#编译器.
如果它有一些其他特殊含义实际影响某些东西,有人可以解释一下吗?
它只是await在方法中创建一个关键字,并对返回类型设置限制,并将其含义更改return为"表示与此调用关联的任务已完成",以及其他一些内务处理细节.
await不会阻止当前的方法
当然可以.为什么你会认为它没有?
它不会阻塞线程,但肯定会阻止该方法.
它只是执行该方法中剩下的代码并在其自己的时间内执行异步操作.
绝对不.这完全是倒退.await与此相反.Await表示如果任务未完成,则返回给您的调用者,并注册该方法的其余部分作为任务的继续.
正如您所看到的,我在GetPlayerAsync上运行了一些异步代码,如果我们深入了解范围并且我们需要访问播放器会发生什么,但它还没有返回播放器呢?
这种情况永远不会发生.
如果执行player时分配给的值不可用,await则await 返回,并且当值可用时(或任务异常完成时),方法的其余部分将恢复.
记住,等待意味着异步等待,这就是我们称之为"等待"的原因. 等待是异步工作流中的一个点,在等待任务完成之前,工作流无法继续.这与你描述等待的方式相反.
同样,请记住异步工作流是什么:它是一组任务,其中这些任务彼此依赖.我们通过await在依赖点放置一个任务来表示一个任务依赖于另一个任务的完成.
让我们更详细地看一下您的工作流程:
var player = await GetPlayerAsync();
foreach (var uPlayer in Players.Values) ...
if (player.Username == "SomeUsername") ...
Run Code Online (Sandbox Code Playgroud)
等待意味着"在获得玩家之前,此工作流程的其余部分无法继续".这实际上是对的吗?如果你想foreach以不执行,直到玩家牵强,那么这是正确的.但是foreach不依赖于播放器,所以我们可以这样重写:
Task<Player> playerTask = GetPlayerAsync();
foreach (var uPlayer in Players.Values) ...
Player player = await playerTask;
if (player.Username == "SomeUsername") ...
Run Code Online (Sandbox Code Playgroud)
请参阅,我们已将依赖点移至工作流程的后期.我们开始"获得玩家"任务,然后我们做foreach,然后在我们需要之前检查玩家是否可用.
如果你相信await某种方式"接听电话并使其异步",那么这应该消除这种信念. await接受一项任务,如果不完整则返回.如果完成,则提取该任务的值并继续."获取播放器"操作已经是异步的,await并不是这样.
如果它不阻止该方法,它如何知道该播放器不为空
它会阻止该方法,或者更确切地说,它会暂停该方法.
在任务完成并提取值之前,该方法将暂停并不会恢复.
它不会阻塞线程.它返回,以便调用者可以继续在不同的工作流程中工作.任务完成后,将继续安排到当前上下文,方法将恢复.