You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用WebView2下载Betfair的XML页面时遇变量无响应问题

问题分析与解决:WebView2获取XML页面后操作无响应

我尝试使用WebView2从Betfair下载并提取XML页面,页面可正常导航,但对result变量的操作(如通过MsgBox显示内容)均无响应,不过代码仍能继续执行并未冻结。相关代码如下:

Private Async Function Process_XML_WebView2(ByVal marketId As String) As Task
        Dim url As String = "https://www.betfair.com/www/sports/exchange/readonly/v1/bymarket?_ak=nzIFcwyWhrlwYMrh&currencyCode=GBP&locale=en_GB&marketIds=" & marketId & "&rollupLimit=2&rollupModel=STAKE&types=MARKET_STATE,RUNNER_STATE,RUNNER_EXCHANGE_PRICES_BEST,RUNNER_DESCRIPTION"

        Dim xmlData As String = Await Download_XML_WebView2(url)
        MsgBox("Start Extract")
        Extract_XML_V3(xmlData, marketId)
    End Function

    Private Async Function Download_XML_WebView2(ByVal url As String) As Task(Of String)
        Dim pageSource As String = ""

        Dim navigationTaskCompletionSource As New TaskCompletionSource(Of Boolean)()
        AddHandler webView.NavigationCompleted, Sub(sender As Object, e As CoreWebView2NavigationCompletedEventArgs)
                                                    navigationTaskCompletionSource.TrySetResult(True)
                                                End Sub

        webView.Source = New Uri(url)
        Await navigationTaskCompletionSource.Task

        Dim script As String = "document.documentElement.outerHTML"
        Dim result As String = Await webView.CoreWebView2.ExecuteScriptAsync(script).ConfigureAwait(False)

        pageSource = result
        MsgBox(pageSource)
        Return pageSource
    End Function

问题根源

  1. UI线程上下文丢失:ConfigureAwait(False)导致Await后的代码脱离UI线程执行,MsgBox作为UI操作在非UI线程无法正常触发,但不会阻塞程序执行。
  2. 事件处理器重复绑定:每次调用Download_XML_WebView2都会新增NavigationCompleted事件处理器,可能引发上下文混乱。
  3. 未校验导航结果:没有判断导航是否成功,即使页面加载失败仍会继续执行后续逻辑。
  4. 字符串未解码:ExecuteScriptAsync返回的是JSON转义后的字符串,直接使用会导致内容格式异常。

修复后的代码

Private Async Function Process_XML_WebView2(ByVal marketId As String) As Task
    Dim url As String = "https://www.betfair.com/www/sports/exchange/readonly/v1/bymarket?_ak=nzIFcwyWhrlwYMrh&currencyCode=GBP&locale=en_GB&marketIds=" & marketId & "&rollupLimit=2&rollupModel=STAKE&types=MARKET_STATE,RUNNER_STATE,RUNNER_EXCHANGE_PRICES_BEST,RUNNER_DESCRIPTION"

    Dim xmlData As String = Await Download_XML_WebView2(url)
    MsgBox("Start Extract")
    Extract_XML_V3(xmlData, marketId)
End Function

Private Async Function Download_XML_WebView2(ByVal url As String) As Task(Of String)
    Dim pageSource As String = ""
    
    ' 使用一次性事件处理器,避免重复绑定
    Using navigationTcs As New TaskCompletionSource(Of Boolean)()
        Dim handler As EventHandler(Of CoreWebView2NavigationCompletedEventArgs) = Nothing
        handler = Sub(sender, e)
                      webView.NavigationCompleted -= handler
                      ' 校验导航是否成功
                      If e.IsSuccess Then
                          navigationTcs.TrySetResult(True)
                      Else
                          navigationTcs.TrySetException(New Exception($"导航失败,错误码:{e.WebErrorStatus}"))
                      End If
                  End Sub
        AddHandler webView.NavigationCompleted, handler

        webView.Source = New Uri(url)
        Await navigationTcs.Task
    End Using

    Dim script As String = "document.documentElement.outerHTML"
    ' 移除ConfigureAwait(False),确保回到UI线程执行
    Dim result As String = Await webView.CoreWebView2.ExecuteScriptAsync(script)

    ' 解码JSON转义的字符串,还原原始HTML内容
    pageSource = System.Web.HttpUtility.JavaScriptStringDecode(result)
    MsgBox(pageSource)
    Return pageSource
End Function

修复说明

  • 移除ConfigureAwait(False),让Await后代码回到UI线程,确保MsgBox等UI操作正常触发。
  • 使用一次性事件处理器,触发后立即移除绑定,避免重复绑定引发的问题。
  • 增加导航成功校验,加载失败时抛出异常,提前终止无效逻辑。
  • 对ExecuteScriptAsync返回的字符串解码,还原真实的HTML内容。

内容的提问来源于stack exchange,提问作者Emu77

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 14:13:17