【问题标题】:VB.NET 2.0 - StackOverflowException when using Thread Safe calls to Windows Forms ControlsVB.NET 2.0 - 对 Windows 窗体控件使用线程安全调用时出现 StackOverflowException
【发布时间】:2011-09-22 13:00:14
【问题描述】:

我有一个 Windows 窗体应用程序,不幸的是,它必须从第二个线程调用控件。我一直在使用http://msdn.microsoft.com/en-us/library/ms171728.aspx 中描述的线程安全模式。过去效果很好。

我现在遇到的具体问题:我有一个 WebBrowser 控件,我正在尝试使用此线程安全模式调用 WebBrowser.Navigate() 方法,结果我得到了 StackOverflow 异常。这是我编写的线程安全导航方法。

Private Delegate Sub NavigateControlCallback(ByRef wb As WebBrowser, ByVal url As String)

Private Sub AsyncNavigate(ByRef wb As WebBrowser, ByVal URL As String)
    Try
        If wb.InvokeRequired Then
            Dim callback As New NavigateControlCallback(AddressOf AsyncNavigate)
            callback(wb, url)
        Else
            wb.Navigate(url)
        End If
    Catch ex As Exception

    End Try
End Sub

是否有一种线程安全的方式与 WinForms 组件进行交互而不会产生这些 StackOverflowExceptions 的副作用?

【问题讨论】:

    标签: vb.net winforms thread-safety .net-2.0 stack-overflow


    【解决方案1】:

    这就是问题所在:

    If wb.InvokeRequired Then
        Dim callback As New NavigateControlCallback(AddressOf AsyncNavigate)
        callback(wb, url)
    Else
    

    在 If 块的第二行,您只是再次调用 AsyncNavigate。直接地。断然地。无需编组到 UI 线程。您应该使用InvokeBeginInvoke

    If wb.InvokeRequired Then
        Dim callback As New NavigateControlCallback(AddressOf AsyncNavigate)
        wb.BeginInvoke(callback(wb, url))
    Else
    

    (旁注:请不要吞下这样的异常......)

    【讨论】:

    • 好吧,这肯定停止了 StackOverflow 异常,但现在导航从未真正发生过。我会去对此做更多的研究。非常感谢。
    • @LamdaComplex:您是否尝试过在wb.Navigate 调用本身上设置断点,以查看它是否被调用?如果您希望后台线程等到回调发生,您当然应该使用Invoke 而不是BeginInvoke
    • @LamdaComplex but now the navigate never actually occurs 这是例外情况,你只是忽略它们。
    • 感谢 Jon,您的解决方案效果很好,但再次证明我需要更仔细地阅读那些 MSDN 文章。至于新问题:我的一个小错字就是问题所在。我传递给该方法的 WebBrowser 引用实际上是错误的,这就是为什么我没有看到按预期进行的导航。
    猜你喜欢
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多