#vb.net #asynchronous #async-await
Вопрос:
Я использую форму ожидания с анимированным gif внутри. Единственный способ, который я нашел для отображения этой формы с анимированным gif «перемещение», — это :
frmWaiting.Show()
Await Task.Run(Sub() AnyKindOfActionInASub)
frmWaiting.Close()
Это хорошо работает, но что, если мне нужно вызвать асинхронную функцию, возвращающую объект, а не простую вспомогательную функцию? Если я это сделаю :
Dim TwitterAccountToAdd As TwitterAccount
frmWaiting.Show()
TwitterAccountToAdd = Await nsTweetInvi.CallTwitterApi.GetApiTwitterDatasAccount(Me.txtTwitterId.Text)
frmWaiting.Close()
Анимированный gif заменяется белым квадратом.
Учитывая, что GetApiTwitterDatasAccount возвращает задачу(Из TwitterAccount), как я могу это сделать?
Комментарии:
1. Лично я не делал много асинхронности, так что просто комментарий, но я считаю, что хитрость в том, что вам все равно нужно обернуть вызов в задачу, затем все еще ждать задачи и в конце проверить
Task.Result
, чтобы найти результат вызова функции.2. Вам нужно посмотреть, что
GetApiTwitterDatasAccount
происходит. Судя по всему, это совершенно нормальная вещьAwait
, но если она делает что-то существенное, помимо ожидания ответа от удаленного хоста, это «что угодно» будет выполняться в потоке пользовательского интерфейса и блокировать вашу анимацию.3. @JoelCoehoorn предложенная вами последовательность ничем не отличается от того, что здесь делается на самом деле. Фактическая разница заключается в том, что исходный код использовался
Task.Run
для планирования потока пула потоков.Task.Run
на самом деле не подходит для ожидания ввода-вывода или сети, как это делает второй, но, как я уже отмечал, если он делает что-то интересное помимо этого ожидания, в потоке пользовательского интерфейса произойдет «что-нибудь интересное».4. На самом
GetApiTwitterDatasAccount
деле асинхронно? Если это так, ожидание этого будет иметь тот же эффект, что и код в первом фрагменте. В противном случае вы можетеTask.Run()
это сделать и ждать результатов, как, ну, в первом фрагменте. В этом случае это было бы , например,dim theText = Me.txtTwitterId.Text dim TwitterAccountToAdd = await Task.Run(Function() nsTweetInvi.CallTwitterApi.GetApiTwitterDatasAccount(theText))
Ответ №1:
Следуя советам Джими, я нашел решение, которое отлично работает.
Private TwitterAccountToAdd As New TwitterAccount
Dim strTwitterId As String = Me.txtTwitterId.Text
Dim frmWaitingTwitter As New frmWaiting
Me.TopMost = False
With frmWaitingTwitter
.TopMost = True
.Show()
.StartPosition = FormStartPosition.CenterScreen
End With
TwitterAccountToAdd = Await Task.Run(Function() CheckAndGetTwitterAccount(strTwitterId))
frmWaitingTwitter.Close()
Me.TopMost = True