VB.NET控制台程序中安全且简便调用Async函数的方法
VB.NET控制台程序安全调用Async函数的正确方式
VB.NET早期版本不支持Async Main,例如以下代码可通过预编译,但最终编译会失败:
Friend Module SomeConsoleApp Friend Async Sub Main Await Task.Delay(1000) End Sub End Module
对应的编译错误信息为:
The 'Main' method cannot be marked 'Async'
有一种常见的简化写法,初看能解决问题:
Friend Module SomeConsoleApp Friend Sub Main() Dim oTask As Task = SomeFunctionAsync() oTask.Wait() End Sub Friend Async Function SomeFunctionAsync() As Task Await Task.Delay(1000) End Function End Module
但这种写法存在隐患:一旦SomeFunctionAsync内部包含阻塞等待操作,就很容易触发死锁。
最安全且简便的两种实现方式
1. 升级到VB 15.5+版本,直接使用Async Main
从VB 15.5开始,官方正式支持异步入口方法,你可以直接编写Async Function Main As Task(推荐)或Async Sub Main,无需额外处理:
Friend Module SomeConsoleApp Friend Async Function Main() As Task Await Task.Delay(1000) ' 执行其他异步业务逻辑 End Function End Module
如果使用Visual Studio,确保项目的语言版本设置为15.5或更高(可通过项目属性 -> 编译 -> 高级编译选项调整)。
2. 兼容旧版本的安全写法
如果需要兼容更早的VB.NET版本,避免使用Wait()或Result方法,改用GetAwaiter().GetResult()来获取异步操作的结果。若异步方法依赖同步上下文,可结合Task.Run将操作委托给线程池执行,彻底规避死锁风险:
Friend Module SomeConsoleApp Friend Sub Main() ' 直接调用异步方法并获取结果,无同步上下文绑定场景下足够安全 SomeFunctionAsync().GetAwaiter().GetResult() ' 若异步方法涉及同步上下文(如UI相关逻辑,控制台场景少见),可改用: ' Task.Run(AddressOf SomeFunctionAsync).GetAwaiter().GetResult() End Sub Friend Async Function SomeFunctionAsync() As Task Await Task.Delay(1000) ' 其他异步逻辑 End Function End Module
GetAwaiter().GetResult()的优势在于,捕获异常时会直接抛出原始异常,而非像Wait()那样包装成AggregateException,便于异常排查。
内容的提问来源于stack exchange,提问作者InteXX
相关产品推荐
相关产品推荐

