I wrote the following WPF sample app in VB.NET 14 using .NET 4.6.1 on VS2015.1:
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
The sample below produces the following output:
- Debug mode: Pre, Disposed, Post
- Release mode: Pre, Post
This is strange. Why would Debug mode execute this code differently than Release mode...?
When I change the using block to a manual try/finally block, the call to window.Dispose() even throws a NullReferenceException:
Dim window = New DisposableWindow()
Try
window.Show()
For index = 1 To 1
Await Task.Delay(100)
Next
Finally
window.Dispose()
End Try
And even more strange stuff: When the for-loop is excluded, the sample works perfectly. I've only let the For-loop run once, to specify the minimum amount of loops the produce the issue. Also feel free to replace the For-loop with a While-loop. It produces the same behavior as the For-loop.
Works:
Using window = New DisposableWindow()
window.Show()
Await Task.Delay(100)
End Using
Now you might think: 'That is strange!'. It gets even worse. I've also made the exact same example in C# (6), where it works perfectly. So in C# both Debug and Release mode result in 'Pre, Disposed, Post' as output.
The samples can be downloaded here:
http://www.filedropper.com/vbsample
http://www.filedropper.com/cssample
I'm pretty stumped at this point. Is this a bug in the VB.NET stack of .NET Framework? Or am I trying to accomplish something strange, which by luck seems the work in C# and partially in VB.NET?
Edit:
Did some more test:
- Disabling compiler optimizations in VB.NET for Release mode, makes it behave like Debug mode (as expected, but wanted to test it, just in case).
- The issue also happens when I target .NET 4.5 (the earliest version where async/await became available).
Update:
This has since been fixed. Public release is planned for version 1.2, but the latest version in the master branch should contain the fix.
See: https://github.com/dotnet/roslyn/issues/7669