Этот код:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
SqlConnectionStuff.OpenSqlConnectionAsync().Wait();
}
... в частности, Wait()
блокирует выполнение потока пользовательского интерфейса. Между прочим, вызов метода async
и его явная блокировка путем вызова Wait
, кстати, отрицательно сказывается на цели async/await
. Это как раскручивать нить только до Join
. Есть моменты, когда это нормально, например, когда подпись метода не может быть изменена на async
(как в консольных приложениях Main
методы до C # 7)
Между тем, следующий код пытается синхронизировать поток из любого текущего потока в поток пользовательского интерфейса, чтобы поток пользовательского интерфейса обновил свойство lblCursorPosition.Text
.
MainWindow.Instance.lblCursorPosition.Dispatcher.Invoke(() =>
{ MainWindow.Instance.lblCursorPosition.Text = "Connection opened!"; });
К сожалению, как мы уже упоминали, поток пользовательского интерфейса уже занят , ожидая завершения OpenSqlConnectionAsync
. Так что теперь у вас есть случай, когда оба конца ждут другого. У вас тупик .
Исправление будет состоять в том, чтобы изменить сигнатуру метода следующим образом:
private async void Window_Loaded(object sender, RoutedEventArgs e) // <-- note async
{
// await synchronously
await SqlConnectionStuff.OpenSqlConnectionAsync(); // await here. No Wait()
}
Вы можете исправить это по-другому, изменив Invoke
на BeginInvoke
. Последний отправляет действие асинхронно в поток пользовательского интерфейса. Чистый эффект будет OpenSqlConnectionAsync
вернет GetSqlConnection
; поток пользовательского интерфейса возобновит работу после Wait()
; и позже обработайте обновление Label
.
MainWindow.Instance.lblCursorPosition.Dispatcher.BeginInvoke(() =>
{ MainWindow.Instance.lblCursorPosition.Text = "Connection opened!"; });