当前位置: 首页 > 知识库问答 >
问题:

为什么可等待的代码会无限期冻结?

蓬威
2023-03-14

我有这样的代码:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim t = DoStuffAsync()
    t.Wait()
    Debug.Print(t.Result)
End Sub

Private Async Function DoStuffAsync() As Task(Of String)
    Await Task.Delay(2000)
    Return "Stuff"
End Function

我知道这不是做这件事的正确方法。以下是我认为可能是正确的方法:

Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim t = DoStuffAsync()
    Debug.Print(Await t)
End Sub

Private Async Function DoStuffAsync() As Task(Of String)
    Await Task.Delay(2000)
    Return "Stuff"
End Function

不过,我只是想知道,为什么在运行第一个代码示例时,它会无限期地挂在t.wait()上?此时代码执行到底发生了什么,即当线程在t.wait()上阻塞时,什么代码“正在运行”?

共有1个答案

权浩邈
2023-03-14

让我们先从实际出发:是的,对结果应该是awaiting而不是wait()ing。现在来回答你为什么会发生这种情况的问题...

在Stephen Cleary的博客文章《Don't Blocking on Async Code》中,他解释了这种情况是如何发生的。以下是他的“发生了什么”演练,对您的方法进行了修改:

  1. 顶级方法button1_click调用doStuffasync(在UI上下文中)。
  2. doStuffasync调用task.delay(仍在上下文中)。
  3. Task.delay返回未完成的任务,指示时间尚未过去。
  4. DoStuffAsync等待task.delay返回的任务。将捕获上下文,稍后将用于继续运行DoStuffAsync方法。doStuffasync返回未完成的任务,指示doStuffasync方法尚未完成。
  5. 顶级方法同步阻止由doStuffasync返回的任务。这将阻塞上下文线程。
  6. …最终,指定的时间将过去,并且延迟任务将完成。
  7. DoStuffAsync的继续操作现在可以运行了,它等待上下文可用,以便在上下文中执行。
  8. 死锁。顶级方法正在阻塞上下文线程,等待doStuffasync完成,而doStuffasync等待上下文空闲以便完成。
 类似资料:
  • 该程序应该使用int 0x10在ASCII中打印一个具有给定字符的金字塔,3行的预期结果(下面代码中使用的数量)将是: A. a a a a a 要编译和运行代码,我使用nasm编译它,然后使用qemu进行仿真: 然而,程序get无法打印所有ASCII值。此外,如果有任何针对nasm代码的调试器,可以让您逐行运行,允许您检查寄存器值,这对学习也很有帮助。

  • 我试图获得适当的‘结构’来监控一个游戏的状态从外部源(s)使用(Tasks)async/await,以便在一个无限循环中运行任务,然而它的当前编写方式似乎只是冻结了我的UI。 到目前为止我得到的是: (在“状态机”类中) 如果没有上面的“task.delay”行,UI将完全冻结。使用“task.delay”行,它不会冻结,但是如果我试图拖动窗口,它会跳回到我开始拖动它的地方。 我对当前代码的假设是

  • 有没有更好的写法呢?由于某种原因,我真的需要这个循环吗?(似乎与有关)

  • 我写了这个简单的代码来获取一个double,并一直询问直到得到一个为止,但是当你给一个string时,它就变成了一个无限循环,我不知道为什么。为什么它会这样?

  • 我正在努力学习如何正确使用async Wait,但我对它有点共同的想法。 在片段中,我试图构建一个对象数组,其中包含我需要的关于我在组件中上传的文件的信息。问题是this.fileInfo中的对象并没有完全等待返回编码图像的promise,而是在我console.logthis.fileInfo时返回此输出: 如您所见,关键图像是一个值未定义的ZoneAwarePromise。你能帮我修一下吗?