使用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
问题根源
- UI线程上下文丢失:
ConfigureAwait(False)导致Await后的代码脱离UI线程执行,MsgBox作为UI操作在非UI线程无法正常触发,但不会阻塞程序执行。 - 事件处理器重复绑定:每次调用
Download_XML_WebView2都会新增NavigationCompleted事件处理器,可能引发上下文混乱。 - 未校验导航结果:没有判断导航是否成功,即使页面加载失败仍会继续执行后续逻辑。
- 字符串未解码:
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¤cyCode=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
相关产品推荐
相关产品推荐

