listView的Invoke运行sub两次



我已经运行以下代码了几天,但是昨天进行了一些调试后,我发现该潜水艇已经射击了两次。一些背景 - 这是一个邮寄应用程序,它运行了我们所有的软件包。我需要在主表单中添加listView,以显示从EasyPost返回的各种速率。当我第一次添加listView时,该应用程序从调试中运行出色,但是在编译后,它将在列表视图填充后完全悬挂。因此,经过几天的搜索,我添加了Invoke方法,该方法允许应用程序GUI在填充ListView后继续进行。因此,首先,我查看是否返回费率,并看到它撞到LVRATES。invokerequired it is ut newoke进行了调用,然后将EasyPostgetServices进行第二次浪费资源,并在EasyPost上为返回的第二款费率造成货物。

>
Private Sub GetEasyPostServices()

    EasyPostGetServices(dictEPFromAddress, dictEPToAddress, dictEPPackage)
    If EasyPostShipment.rates.Count > 0 Then
        If lvRates.InvokeRequired Then
            lvRates.Invoke(New MethodInvoker(AddressOf GetEasyPostServices))
        Else
            For Each rate As Rate In EasyPostShipment.rates
                lvRates.Items.Add(New ListViewItem({rate.carrier, rate.rate, UCase(rate.service), rate.id}))
            Next
        End If
    Else
        MsgBox("Based on your inputs or preferences, no shipping services were available. Shipping services shown ignore your preferences. If none are shown, there are no shipping services available for this order.")
    End If
End Sub

我的问题是,为什么代码运行两次以及如何防止其发生。我已经移动了调用,但是当我从exe跑步时,我尝试了GUI冻结的所有其他内容。

这是基于您最初的问题。我在单击按钮中添加了一个背景工作人员,以导致geteAsyPostServices开始在非UI线程上运行。此处的关键是如何正确调用UI调用。底部的三种方法表明。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    ' this method is running on the UI thread as it handles a UI event
    Dim bw As New System.ComponentModel.BackgroundWorker()
    AddHandler bw.DoWork, New System.ComponentModel.DoWorkEventHandler(Sub(oo, ee) GetEasyPostServices())
    ' this call causes GetEasyPostServices to run on a non-UI thread
    bw.RunWorkerAsync()
End Sub
Private Sub GetEasyPostServices()
    ' running on a non-UI thread. Any UI calls must be invoked
    Cursor.Current = Cursors.WaitCursor
    Try
        Dim frAddress As New Dictionary(Of String, Object)() From {
            {"street1", "12345 Hill Dr"},
            {"street2", ""},
            {"city", "sometown"}}
        Dim toAddress As New Dictionary(Of String, Object)() From {
            {"street1", sAdd1},
            {"city", sCity},
            {"state", sRegion},
            {"verifications", New List(Of String)() From {"delivery"}}}
        Dim package As New Dictionary(Of String, Object)
        If GlobalVariables.giLength > 0 Then
            package.Add("length", GlobalVariables.giLength.ToString)
            package.Add("width", GlobalVariables.giWidth.ToString)
            package.Add("height", GlobalVariables.giHeight.ToString)
            package.Add("weight", (sLbs * 16) + sOz)
        End If
        EasyPostGetServices(frAddress, toAddress, package)
        If EasyPostShipment.rates.Count > 0 Then
            ' hide the UI invocation logic in methods
            updateListView()
        Else
            MsgBox("Based on your inputs or preferences, no shipping services were available. Shipping services shown ignore your preferences. If none are shown, there are no shipping services available for this order.")
            clearAndFocusTbOrder()
        End If
    Finally
        Cursor.Current = Cursors.Default
    End Try
End Sub
' these methods manage their own UI invocation.
Private Sub updateListView()
    If lvRates.InvokeRequired Then
        lvRates.Invoke(New Action(AddressOf updateListView))
    Else
        lvRates.Visible = True
        lvRates.Items.Clear()
        For Each rate As Rate In EasyPostShipment.rates
            lvRates.Items.Add(New ListViewItem({rate.carrier, rate.rate, UCase(rate.service), rate.id}))
        Next
        SortListView()
        lvRates.Items(0).Selected = True
        Button1.Visible = True
    End If
End Sub
Private Sub SortListView()
    If lvRates.InvokeRequired Then
        lvRates.Invoke(New Action(AddressOf SortListView))
    Else
        lvRates.Sort()
    End If
End Sub
Private Sub clearAndFocusTbOrder()
    If tbOrderID.InvokeRequired Then
        tbOrderID.Invoke(New Action(AddressOf clearAndFocusTbOrder))
    Else
        tbOrderID.Clear()
        tbOrderID.Focus()
    End If
End Sub

这全是关于什么,何处和为什么调用的。在您的示例中,尚不清楚geteasypostservices是否在UI上开始。我没有引起它,因此我可以演示如何正确调用UI调用。然后,您需要调用UI调用,因为它当前不在UI线程上。那就是"为什么"。

此外,在UI线程上运行最少的代码以防止不必要的处理和悬挂UI线程是关键。您的原始配置一次运行了所有代码,然后在UI线程上再次运行

最新更新