Return 类型 Task.Run 与 Task.Factory.StartNew
Return type of Task.Run vs. Task.Factory.StartNew
我一直在阅读和重读 Stephen Cleary 的文章 StartNew is Dangerous and Stephen Toub's article Task.Run vs Task.Factory.StartNew。我正在尝试理解这一点。
给定以下代码:
Dim s = Await Task.Factory.StartNew(New Func(Of Task(Of String))(
Async Function()
Await Task.Delay(10000)
Return "Hello"
End Function))
Dim t = Await Task.Run(New Func(Of Task(Of String))(
Async Function()
Await Task.Delay(10000)
Return "Hello"
End Function))
为什么 s
是 Task(Of String)
类型而 t
是 String
类型(我希望如此)?
我还可以做到以下几点:
Dim u = Await New Func(Of Task(Of String))(
Async Function()
Await Task.Delay(10000)
Return "Hello"
End Function).Invoke()
其中 u
是一个 String
,我可以添加函数:
Async Function GetValueAsync() As Task(Of String)
Await Task.Delay(10000)
Return "Hello"
End Function
然后像这样使用它:
Dim v = Await GetValueAsync()
和v
也是一个String
.
那么为什么 s
不是字符串?
在 Stephen Cleary 的文章(上面链接)中,他说:
[Task.Factory.StartNew] Does not understand async delegates...The problem
is that when you pass an async delegate to StartNew, it’s natural to
assume that the returned task represents that delegate. However, since
StartNew does not understand async delegates, what that task actually
represents is just the beginning of that delegate.
我觉得这是整个事情的关键,但我不明白"what that task actually represents is just the beginning of that delegate.""the beginning of that delegate"是什么意思?
您可以将 Await
视为 "unwrapping" 对结果类型 T
的 Task(Of T)
。
Why is it that s is of type Task(Of String) and t is of type String (which I would expect)?
Task.Factory.StartNew(New Func(Of Task(Of String))(...)
的类型是 Task(Of Task(Of String))
,因此 Await
将其解包为 Task(Of String)
。
Task.Run(New Func(Of Task(Of String))(...)
的类型是 Task(Of String)
,因此 Await
将其解包为 String
。
What does "the beginning of that delegate" mean?
正如我在 Async Intro 中描述的那样,每个异步方法都开始同步执行,并且仅在第一个 Await
时变为异步。因此,如果您使用 Task.Factory.StartNew
,它 return 就是 Task(Of Task(Of T))
。 "outer" 任务表示委托的同步执行,直到第一次 Await
决定屈服于其调用者。那时,Await
将 return 一个 Task(Of T)
给它的调用者。此 returned 任务是 Task(Of Task(Of T))
的 "inner" 任务,它表示该异步委托的 完成 。
但是您真正需要知道的唯一一件事就是只使用 Task.Run
而不是 Task.Factory.StartNew
。
我一直在阅读和重读 Stephen Cleary 的文章 StartNew is Dangerous and Stephen Toub's article Task.Run vs Task.Factory.StartNew。我正在尝试理解这一点。
给定以下代码:
Dim s = Await Task.Factory.StartNew(New Func(Of Task(Of String))(
Async Function()
Await Task.Delay(10000)
Return "Hello"
End Function))
Dim t = Await Task.Run(New Func(Of Task(Of String))(
Async Function()
Await Task.Delay(10000)
Return "Hello"
End Function))
为什么 s
是 Task(Of String)
类型而 t
是 String
类型(我希望如此)?
我还可以做到以下几点:
Dim u = Await New Func(Of Task(Of String))(
Async Function()
Await Task.Delay(10000)
Return "Hello"
End Function).Invoke()
其中 u
是一个 String
,我可以添加函数:
Async Function GetValueAsync() As Task(Of String)
Await Task.Delay(10000)
Return "Hello"
End Function
然后像这样使用它:
Dim v = Await GetValueAsync()
和v
也是一个String
.
那么为什么 s
不是字符串?
在 Stephen Cleary 的文章(上面链接)中,他说:
[Task.Factory.StartNew] Does not understand async delegates...The problem is that when you pass an async delegate to StartNew, it’s natural to assume that the returned task represents that delegate. However, since StartNew does not understand async delegates, what that task actually represents is just the beginning of that delegate.
我觉得这是整个事情的关键,但我不明白"what that task actually represents is just the beginning of that delegate.""the beginning of that delegate"是什么意思?
您可以将 Await
视为 "unwrapping" 对结果类型 T
的 Task(Of T)
。
Why is it that s is of type Task(Of String) and t is of type String (which I would expect)?
Task.Factory.StartNew(New Func(Of Task(Of String))(...)
的类型是 Task(Of Task(Of String))
,因此 Await
将其解包为 Task(Of String)
。
Task.Run(New Func(Of Task(Of String))(...)
的类型是 Task(Of String)
,因此 Await
将其解包为 String
。
What does "the beginning of that delegate" mean?
正如我在 Async Intro 中描述的那样,每个异步方法都开始同步执行,并且仅在第一个 Await
时变为异步。因此,如果您使用 Task.Factory.StartNew
,它 return 就是 Task(Of Task(Of T))
。 "outer" 任务表示委托的同步执行,直到第一次 Await
决定屈服于其调用者。那时,Await
将 return 一个 Task(Of T)
给它的调用者。此 returned 任务是 Task(Of Task(Of T))
的 "inner" 任务,它表示该异步委托的 完成 。
但是您真正需要知道的唯一一件事就是只使用 Task.Run
而不是 Task.Factory.StartNew
。