我在VS2015.1上使用.NET 4.6.1在VB.NET 14中编写了以下WPF示例应用程序:
Class MainWindow
Public Sub New()
InitializeComponent()
End Sub
Private Async Sub Button_Click(sender As Object, e As RoutedEventArgs)
MessageBox.Show("Pre")
Using window = New DisposableWindow()
window.Show()
For index = 1 To 1
Await Task.Delay(100)
Next
End Using
MessageBox.Show("Post")
End Sub
Class DisposableWindow
Inherits Window
Implements IDisposable
Public Sub Dispose() Implements IDisposable.Dispose
Me.Close()
MessageBox.Show("Disposed")
End Sub
End Class
End Class
下面的示例生成以下输出:
- 调试模式:Pre,Disposed,Post
- 发布模式:Pre,Post
这很奇怪。为什么Debug模式执行此代码的方式与Release模式不同?
当我将using块更改为手动try / finally块时,对window.Dispose()的调用甚至会抛出NullReferenceException:
Dim window = New DisposableWindow()
Try
window.Show()
For index = 1 To 1
Await Task.Delay(100)
Next
Finally
window.Dispose()
End Try
甚至更奇怪的东西:当排除for循环时,样本完美地运行。我只让For-loop运行一次,以指定产生问题的最小循环量。也可以随意使用While循环替换For循环。它产生与For循环相同的行为。
作品:
Using window = New DisposableWindow()
window.Show()
Await Task.Delay(100)
End Using
现在你可能会想:'这很奇怪!'。情况变得更糟。 我也在C#(6)中做了完全相同的例子。所以在C#中,Debug和Release模式都会导致'Pre,Disposed,Post'作为输出。
样本可以在这里下载:
http://www.filedropper.com/vbsample
http://www.filedropper.com/cssample
我在这一点上很难过。这是.NET Framework的VB.NET堆栈中的错误吗?或者我是否想要完成一些奇怪的事情,运气似乎是C#中的工作,部分是在VB.NET中?
编辑:
做了一些测试:
- 在VB.NET中禁用发布模式的编译器优化,使其行为类似于调试模式(正如预期的那样,但想要测试它,以防万一)。
- 当我以.NET 4.5(async / await可用的最早版本)为目标时,也会出现这个问题。
更新:
这已经得到修复。版本1.2计划公开发布,但主分支中的最新版本应包含修复程序。