Я написал следующее примерное приложение WPF в VB.NET 14, используя .NET 4.6.1 на 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
Пример ниже дает следующий результат:
- Режим отладки: Pre, Disposed, Post
- Режим выпуска: Pre, Post
Это странно. Почему режим Debug выполняет этот код иначе, чем режим Release...?
Когда я меняю блок использования на ручной блок 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-loop исключено, образец работает отлично. Я разрешаю только цикл For-loop, чтобы указать минимальное количество циклов, которые создают проблему. Также не стесняйтесь заменять For-loop на цикл While. Он производит то же поведение, что и For-loop.
Работы:
Using window = New DisposableWindow()
window.Show()
Await Task.Delay(100)
End Using
Теперь вы можете подумать: "Это странно!". Это становится еще хуже. Я также сделал тот же пример в С# (6), где он отлично работает. Таким образом, в С# оба режима Debug и Release приводят к выводу "Pre, Disposed, Post" в качестве вывода.
Сэмплы можно скачать здесь:
http://www.filedropper.com/vbsample
http://www.filedropper.com/cssample
На данный момент я очень взволнован. Является ли это ошибкой в стеке VB.NET.NET Framework? Или я пытаюсь выполнить что-то странное, что по счастью кажется работой на С# и частично в VB.NET?
Edit:
Проделал еще несколько тестов:
- Отключение оптимизаций компилятора в режиме VB.NET для выпуска, приводит к тому, что он ведет себя как режим отладки (как и ожидалось, но хотел проверить его на всякий случай).
- Проблема также возникает, когда я нацелен на .NET 4.5 (самая ранняя версия, где async/await стал доступен).
Update:
С тех пор исправлено. Публичный релиз запланирован на версию 1.2, но последняя версия в главной ветке должна содержать исправление.