如何使用异步/等待进程的结果列表填充列表框

问题描述 投票:0回答:1

我正在尝试利用异步/等待模式,使用 HttpClient post 请求的结果填充列表框。 该应用程序是 Excel VSTO。 该列表框位于 Excel 任务窗格中。 当我尝试填充列表框时收到此错误消息:

System.InvalidOperationException
  HResult=0x80131509
  Message=Cross-thread operation not valid: Control 'lbo1' accessed from a thread other than the thread it was created on.
  Source=SpenHistorianClient
  StackTrace:
   at SpenHistorianClient.ucEvents.PopulateListBox() in C:\_VSSWorkArea\SPENHistorianClient\SpenHistorianClient\ucEvents.vb:line 410
   at SpenHistorianClient.ucEvents.VB$StateMachine_145_btnTagSearch_Click.MoveNext() in C:\_VSSWorkArea\SPENHistorianClient\SpenHistorianClient\ucEvents.vb:line 396

相关代码如下:

 Private Async Sub btnTagSearch_Click(sender As Object, e As EventArgs) Handles btnTagSearch.Click

      Dim filterText As String = Nothing
      Dim itemType As String = Nothing
      Dim cnt As Long


      Try

           _filteredItems = New TagDefinitions
           filterText = txtFilter.Text

           Await Globals.ThisAddIn.QueryTagList(Globals.ThisAddIn.WebServices(cboSource.SelectedIndex), _filterText, _itemType)

           _filteredItems = Globals.ThisAddIn.GetFilteredTagList(filterText)

           PopulateListBox()

      Catch ex As Exception
           Throw
      End Try
 End Sub
 Public Sub PopulateListBox()

      Try
           For Each item In _filteredItems
                _activeLbo.Items.Add(item.TagName)
           Next

           'Now we have populated the listbox clear the collection as we have no further need of it at this time
           _filteredItems.Clear()

      Catch ex As Exception
           Throw
      End Try

 End Sub

我没想到会出现跨线程问题,因为类变量 _filteredItems 和列表框都在 TaskPane 中定义,我将其理解为 UI 线程,我读过许多讨论列表框跨线程的帖子代表和后台工作人员的使用,但是我很难将这些知识转移到我的特定环境中。

vb.net async-await listbox
1个回答
0
投票

好吧,最后我成功解决了。 最终得到以下解决方案:

 Private Async Sub btnTagSearch_Click(sender As Object, e As EventArgs) Handles btnTagSearch.Click

      Dim filterText As String = Nothing
      Dim itemType As String = Nothing
      Dim cnt As Long

      Try

           _filteredItems = New TagDefinitions
           filterText = txtFilter.Text

           Await Globals.ThisAddIn.QueryTagList(Globals.ThisAddIn.WebServices(cboSource.SelectedIndex), _filterText, _itemType)

           _filteredItems = Await Globals.ThisAddIn.GetFilteredTagList(filterText)
           Invoke(New PopulateListBoxHandler(
           AddressOf PopulateListBox))

      Catch ex As Exception
           Throw
      End Try
 End Sub
 Private Delegate Sub PopulateListBoxHandler()
 Public Sub PopulateListBox()

      Try
           For Each item In _filteredItems
                _activeLbo.Items.Add(item.TagName)
           Next

           'Now we have populated the listbox clear the collection as we have no further need of it at this time
           _filteredItems.Clear()

      Catch ex As Exception
           Throw
      End Try

 End Sub
© www.soinside.com 2019 - 2024. All rights reserved.