Вызов асинхронной функции в задаче.Выполнить

#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