【发布时间】:2020-10-08 18:14:28
【问题描述】:
我确信这个问题以前曾以多种形式被问过,但我正在努力寻找一些东西来澄清我的理解。
据我了解,asynchronously 在 .Net 中运行某些代码部分的概念是基于将工作发送到多个线程,以便它可以与其他工作并行运行。在某些情况下,我们需要等待这项工作完成,然后才能继续下一件事情,而在其他情况下,我们不需要。我主要对如何处理这些差异感到困惑。
我可以使用各种类比,但让我们看看一个建筑商或建筑商团队建造房屋。在不同的阶段,团队正在一起处理不同的任务,或者一起完成一个任务,这里有一个非常简化的演练。
- 第一项任务是基础工作。没有什么可做的,所以每个人都必须努力挖掘基础。
- 我们需要先完成基础工作,然后才能做其他事情。
- 地基工程完成后,我们开始砌块并砌墙。
- 现在我们有电工和水管工进来的墙
- 他们各自的任务被发送到每个行业团队并并行运行以安装第一次修复布线和管道工作。
- 与此同时,有人联系了 Royal Mail 以将此新地址添加到他们的邮政编码/地址数据库中。
- 水管工和电工已经完成,我们可以开始石膏板了。 .....等
在这个类比中,我们有Task的三种类型;
- 必须先完成前两项工作(基础工程和砌块工程),然后才能完成其他任何工作,因此我们在主工作线程中连续运行它们。
- 电工和水管工是两个单独的线程一起运行,他们不需要互相等待完成,但我们可能需要知道或两者是否已完成。李>
- 邮政编码数据库对我们的新房子的建造没有影响,所以作为一个建筑商我们对此没有兴趣,我们只是把它送到另一个团队(皇家邮政),他们做他们的事情,我们没有真正需要知道什么时候完成,所以这是一个发送后忘记的任务。
我在 SO 上发现了这个问题:
How to put this function inside a separate thread
很有帮助,主要是“igrimpe”的回复,我复制一下他的代码:
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' fire and forget:
Task.Run(Sub() FooA()).ContinueWith(Sub() FooB()).ContinueWith(Sub() FooC())
Console.WriteLine("Button1 done")
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
' fire and forget:
Task.Run(Sub()
FooA()
FooB()
FooC()
End Sub)
Console.WriteLine("Button2 done")
End Sub
Private Async Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
' wait but dont block:
Await Task.Run(Sub()
FooA()
FooB()
FooC()
End Sub)
Console.WriteLine("Button3 done")
End Sub
Private Sub FooA()
Threading.Thread.Sleep(1000)
Console.WriteLine("A")
End Sub
Private Sub FooB()
Threading.Thread.Sleep(1000)
Console.WriteLine("B")
End Sub
Private Sub FooC()
Threading.Thread.Sleep(1000)
Console.WriteLine("C")
End Sub
End Class
他说“一劳永逸”,我认为这是我的邮政编码类比,“等待但不要阻塞”是电工和水管工?在他的示例代码中,这些作业将在各自的 CPU 线程上分别运行,我对吗?
有人可以帮助编写明确概述我上面提到的案例的代码,特别是确定单独或多个任务何时完成,无论是一起还是单独完成,并确保我了解如何触发我不需要响应的任务。
另外
这个函数:
Public Async Sub Report(Message As String)
Task.Run(Sub() Write(Message) )
End Sub
它们似乎相互矛盾,在主要的Sb 声明中它说这将同步运行,但是我声明Task 它说因为没有await,该方法将在之前继续运行任务可能已经完成 - 在这种情况下(即发即弃)我不在乎。在运行之前添加Await 可以修复此警告,但我不清楚这是否真的是一场火灾,现在就忘了?
【问题讨论】:
-
"... 在 .Net 中异步运行某些代码部分的概念是基于将工作发送到多个线程..." - There is no thread
-
异步不是并发。线程是一个单独的概念。使用单个线程完全有可能实现您所要求的一切。异步只是意味着我们不做阻塞调用。
-
我建议您阅读 Stephen Cleary 关于此事的整个系列博客文章。
-
好的,谢谢,我会的。
标签: .net multithreading asp.net-core async-await task