我最近看到了关于TPL和异步模式的一些演示,所以我开始了一个小宠物项目来尝试一些事情。 (异步和并行的东西)
我注意到SqlConnection有一个OpenAsync()方法,所以我想尝试等待这个。据我所知,await关键字告诉compliler检查操作是否完成,如果不是,它会将其余代码转换为continuation任务。我也明白我仍然可以调试代码。但是,我遇到了一些问题。
我写了以下简单的测试代码:
Async Sub Gogo()
Try
Await connection1.OpenAsync()
Catch ex As Exception
Console.WriteLine(ex)
End Try
SomeCode()
End Sub
当我运行此代码(控制台应用程序)时会发生什么我确实得到了await语句,但没有进一步。我尝试在catch语句和try块后面的代码中设置断点。两者都没有到达,控制台应用程序只是退出。我不明白这里会发生什么。
我正在使用VS2012更新1,(VB).Net 4.5。此外,因为我怀疑发生了一些错误(这似乎没有任何意义,因为代码在我使其同步时工作)我配置app.config以升级未观察到的异常:
<runtime>
<ThrowUnobservedTaskExceptions enabled="true"/>
</runtime>
但是,到目前为止我没有得到任何例外。 我错过了什么?请帮助:)
答案 0 :(得分:6)
两者都未到达,控制台应用程序只是退出。
问题是您在控制台应用程序中使用它。如果你在Windows窗体或WPF应用程序中做同样的事情,你会看到非常不同的行为。
当您调用Await
时,异步操作会尝试捕获调用方的同步上下文,然后继续该上下文。在控制台应用程序中,没有同步上下文(因为没有消息泵等),因此创建的continuation将在ThreadPool线程上进行调度。
启动异步操作,然后继续操作 - 控制台应用程序结束,因为它到达Main()例程的末尾,之后你永远不会“看到”这些东西。 / p>
如果您希望看到这些内容发生,您需要在控制台应用程序中添加一些内容以防止它完成。例如,您可以使用ManualResetEvent
并在SomeCode()
之后设置它,并在Main()例程中调用WaitOne()
。这将使应用程序保持活动状态,直到异步操作完成。
话虽如此,如果您正在尝试理解Async
/ Await
,我建议您在GUI应用程序中“播放”而不是控制台应用程序。当您安装了适当的同步上下文时,可以更加简单地查看和了解发生的情况,这在Windows窗体和WPF中会自动发生。