在VB.NET中,Task.Run应该如何调用异步方法?

13

给定一个既包含 CPU 工作又包含 IO 工作的异步方法,例如:

Public Async Function RunAsync() As Task
    DoWork()
    Await networkStream.WriteAsync(buffer, 0, buffer.Length).ConfigureAwait(False)
End Function

以下哪个选项是在Visual Basic中从Task.Run调用异步方法的最佳方法,为什么?

在VB中,哪个与C#中的Task.Run(() => RunAsync())等效?

Await Task.Run(Function() RunAsync())
' or
Await Task.Run(Sub() RunAsync())

在Task.Run中,Async/Await关键字是必需的还是多余的?这个评论声称它们是多余的,但是这个答案表明在某些情况下可能是必需的:

Await Task.Run(Async Function()
                   Await RunAsync()
               End Function)

在Task.Run中使用ConfigureAwait有什么作用?

Await Task.Run(Function() RunAsync().ConfigureAwait(False))

Await Task.Run(Async Function()
                   Await RunAsync().ConfigureAwait(False)
               End Function)

上述的5个Task.Run选项中,哪个是最佳实践?

注意:有一个类似的问题如何在Task.Run内调用异步方法?但它是针对C#的,所选答案有负面评分,并未涉及ConfigureAwait。


3
让我们问另一个问题:为什么你想要在已经是异步方法的基础上使用 Task.Run 来包装它,而不只是使用 Await SendAsync() 呢? - Peter Bons
这只是一个简单的例子,实际使用会更加复杂,涉及到输入输出和CPU操作,因此最好在线程池上运行。 - Mike Henry
即使如此,底层的异步方法已经在自己的线程上运行或等待IO完成。因此,你可能会在原始线程之上创建另一个线程。我的观点是,Task.Run旨在运行非异步方法。 - Peter Bons
我理解你对大多数IO情况的观点。但是它可能在主线程上运行CPU工作,这是不可取的吗?这个答案解释了何时使用Task.Run可能是可取的。 - Mike Henry
1
这是一个人们需要理解的重要主题。我需要这个解决方案,因为我提供了一个仅公开异步函数的发送电子邮件库,并且我不想将所有需要发送电子邮件的调用子程序转换为异步函数。 - Hawkeye
1
值得注意的是:我最近发现,C#中的lambda表达式在FuncAction之间没有明显的区分。要区分它们,需要确定lambda表达式方法体中的代码是否返回结果。如果有返回结果,则为Func,否则为Action - InteXX
1个回答

28

在VB中,相当于C#的Task.Run(() => RunAsync())的代码是什么?

我已经很久没有用VB了,但似乎这不是Sub,所以我会选择:

Task.Run(Function() RunAsync())

在 Task.Run 中使用 Async/Await 关键字是必要的还是多余的?

我有一篇关于这个主题的博客文章。在这种情况下,它们是多余的,因为委托是微不足道的。

在 Task.Run 中使用 ConfigureAwait 有用吗?

只有当你使用 Await 时才有用。


感谢提供信息和有用博客文章的链接。据我所知,在这种简单情况下,Task.Run(Function() RunAsync()) 是最佳选择,因为它只是通过传递,并且在等待 Task.Run 时未捕获的异常仍将在 AggregateException 中捕获。根据博客文章,似乎 Await/Async 关键字和因此 ConfigureAwait 在从 Task.Run 进行更复杂的调用时可能会有用。 - Mike Henry
在 lambda 中,使用 Function vs Sub 会更好,因为 lambda 可以返回一个 Task 而不是 void。 - Mike Henry
1
@MikeHenry:是的,除了AggregateExceptionTask.Run不会包装成AggregateException;只要使用Await而不是Wait/Result,您就不必处理聚合异常。 - Stephen Cleary
啊,这样就说得通了。感谢您的澄清。 - Mike Henry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接