Fox*_*Fox 6 .net c# vb.net asynchronous async-await
在控制台应用程序中。我需要从主线程加载一些长时间运行的代码(网络内容、REST 调用)。我想将它传递给后台线程并且不阻塞调用线程。我将调用该方法中的事件来处理其结果。
这样做有什么区别吗?
public async Task MainThreadAsync() {
_ = Task.Run(async () => await DoSomethingAsync());
// Continue with other stuff and don't care about DoSomethingAsync()
}
private async Task DoSomethingAsync() {
// Doing long running stuff
}
Run Code Online (Sandbox Code Playgroud)
或这样做?
public async Task MainThreadAsync() {
DoSomethingAsync();
// Continue with other stuff and don't care about DoSomethingAsync()
}
private async void DoSomethingAsync() {
// Doing long running stuff
}
Run Code Online (Sandbox Code Playgroud)
VB.Net:
Public Async Function MainThreadAsync() As Task
Task.Run(Async Function() As Task
Await DoSomethingAsync()
End Function)
' Continue with other stuff and don't care about DoSomethingAsync()
End Function
Private Async Function DoSomethingAsync() As Task
' Doing long running stuff
End Function
Run Code Online (Sandbox Code Playgroud)
与
Public Async Function MainThreadAsync() As Task
DoSomethingAsync()
' Continue with other stuff and don't care about DoSomethingAsync()
End Function
Private Async Sub DoSomethingAsync()
' Doing long running stuff
End Sub
Run Code Online (Sandbox Code Playgroud)
或者还有更好的方法吗?另外,c#和vb.net在这方面有区别吗?
首先:不要使用 async void
. 我意识到它表达了你想要的语义,但是有一些框架内部结构如果遇到它就会主动爆炸(这是一个漫长而无趣的故事),所以:不要进行这种实践。
让我们假设我们有:
private async Task DoSomething() {...}
Run Code Online (Sandbox Code Playgroud)
出于这个原因,在这两种情况下。
这里的主要区别是,从调用者的角度来看,不能保证不会DoSomething
同步运行。所以在这种情况下:
public async task MainThread() {
_ = DoSomething(); // note use of discard here, because we're not awaiting it
}
Run Code Online (Sandbox Code Playgroud)
DoSomething
将在主线程上运行至少到第一个await
- 具体来说,第一个incomplete await
。好消息是:您只需添加:
await Task.Yield();
Run Code Online (Sandbox Code Playgroud)
作为第一行DoSomething()
,它保证立即返回给调用者(因为Task.Yield
本质上总是不完整的),避免必须通过Task.Run
. 在内部,Task.Yield()
执行与非常相似的Task.Run()
操作,但它可以跳过一些不必要的部分。
把所有这些放在一起 - 如果是我,我会:
public async Task MainThread() {
_ = DoSomething();
// Continue with other stuff and don't care about DoSomething()
}
private async Task DoSomething() {
await Task.Yield();
// Doing long running stuff
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5844 次 |
最近记录: |